├── .document ├── .gitignore ├── .rspec ├── LICENSE ├── README.rdoc ├── Rakefile ├── VERSION ├── autotest └── discover.rb ├── lib ├── userapi.rb └── userapi │ ├── auth.rb │ └── user.rb └── spec ├── spec_helper.rb └── userapi ├── auth_spec.rb └── user_spec.rb /.document: -------------------------------------------------------------------------------- 1 | README.rdoc 2 | lib/**/*.rb 3 | bin/* 4 | features/**/*.feature 5 | LICENSE 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## MAC OS 2 | .DS_Store 3 | 4 | ## TEXTMATE 5 | *.tmproj 6 | tmtags 7 | 8 | ## EMACS 9 | *~ 10 | \#* 11 | .\#* 12 | 13 | ## VIM 14 | *.swp 15 | 16 | ## PROJECT::GENERAL 17 | coverage 18 | rdoc 19 | pkg 20 | 21 | ## PROJECT::SPECIFIC 22 | *.gemspec 23 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010 Max Riveiro 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = userapi-ruby 2 | 3 | Description goes here. 4 | 5 | == Note on Patches/Pull Requests 6 | 7 | * Fork the project. 8 | * Make your feature addition or bug fix. 9 | * Add tests for it. This is important so I don't break it in a 10 | future version unintentionally. 11 | * Commit, do not mess with rakefile, version, or history. 12 | (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull) 13 | * Send me a pull request. Bonus points for topic branches. 14 | 15 | == Copyright 16 | 17 | Copyright (c) 2010 Max Riveiro. See LICENSE for details. 18 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rubygems' 2 | require 'rake' 3 | 4 | begin 5 | require 'jeweler' 6 | Jeweler::Tasks.new do |gem| 7 | gem.name = "userapi-ruby" 8 | gem.summary = %Q{Ruby Gem for interacting with VKontakte.Ru UserAPI} 9 | gem.description = %Q{UserAPI is an application programming interface (API), which enables anyone to create social networks and other projects based on Vkontakte data storage. And I have a little problem - there is no Ruby Gem to work with this API. So this Gem will realize some features of UserAPI} 10 | gem.email = "kavu13@gmail.com" 11 | gem.homepage = "http://github.com/kavu/userapi-ruby" 12 | gem.authors = ["Max Riveiro"] 13 | gem.add_dependency "httparty", ">= 0.6.1" 14 | gem.add_development_dependency "rspec", ">= 2.0.0" 15 | gem.add_development_dependency "fakeweb", ">= 1.2.8" 16 | gem.files = FileList['lib/**/*.rb'] 17 | # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings 18 | end 19 | Jeweler::GemcutterTasks.new 20 | rescue LoadError 21 | puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler" 22 | end 23 | 24 | require 'rspec/core/rake_task' 25 | RSpec::Core::RakeTask.new(:spec) do |spec| 26 | spec.pattern = 'spec/**/*_spec.rb' 27 | end 28 | 29 | RSpec::Core::RakeTask.new(:rcov) do |spec| 30 | spec.pattern = 'spec/**/*_spec.rb' 31 | spec.rcov = true 32 | spec.rcov_opts = %q[--exclude "spec"] 33 | end 34 | 35 | task :spec => :check_dependencies 36 | 37 | begin 38 | require 'reek/adapters/rake_task' 39 | Reek::RakeTask.new do |t| 40 | t.fail_on_error = true 41 | t.verbose = false 42 | t.source_files = 'lib/**/*.rb' 43 | end 44 | rescue LoadError 45 | task :reek do 46 | abort "Reek is not available. In order to run reek, you must: sudo gem install reek" 47 | end 48 | end 49 | 50 | begin 51 | require 'roodi' 52 | require 'roodi_task' 53 | RoodiTask.new do |t| 54 | t.verbose = false 55 | end 56 | rescue LoadError 57 | task :roodi do 58 | abort "Roodi is not available. In order to run roodi, you must: sudo gem install roodi" 59 | end 60 | end 61 | 62 | task :default => :spec 63 | 64 | require 'rake/rdoctask' 65 | Rake::RDocTask.new do |rdoc| 66 | version = File.exist?('VERSION') ? File.read('VERSION') : "" 67 | 68 | rdoc.rdoc_dir = 'rdoc' 69 | rdoc.title = "userapi-ruby #{version}" 70 | rdoc.rdoc_files.include('README*') 71 | rdoc.rdoc_files.include('lib/**/*.rb') 72 | end 73 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 0.0.1 2 | -------------------------------------------------------------------------------- /autotest/discover.rb: -------------------------------------------------------------------------------- 1 | Autotest.add_discovery { "rspec2" } -------------------------------------------------------------------------------- /lib/userapi.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | require 'httparty' 4 | require 'userapi/auth' 5 | require 'userapi/user' 6 | 7 | module VK 8 | 9 | end 10 | -------------------------------------------------------------------------------- /lib/userapi/auth.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | require 'singleton' 4 | 5 | module VK 6 | class Auth 7 | include Singleton 8 | include HTTParty 9 | 10 | base_uri 'login.userapi.com' 11 | 12 | class << self 13 | attr_reader :sid, :user_id 14 | end 15 | 16 | def self.login!(login,password) 17 | begin 18 | self.get "/auth?login=force&site=2&email=#{login}&pass=#{password}", :no_follow => true 19 | rescue HTTParty::RedirectionTooDeep => response 20 | @sid = /.*;sid=(\w*)$/.match(response.response.header['location'])[1] 21 | @user_id = /remixmid=(\d+)/.match(response.response.header['set-cookie'])[1] 22 | return true 23 | else 24 | raise VK::AuthFail 25 | end 26 | end 27 | end 28 | 29 | class AuthFail < Exception; end 30 | end 31 | -------------------------------------------------------------------------------- /lib/userapi/user.rb: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | 3 | require 'json' 4 | 5 | module VK 6 | class User 7 | include HTTParty 8 | base_uri 'userapi.com' 9 | 10 | def initialize(id) 11 | @id = id 12 | end 13 | 14 | def user_id(p) 15 | 123 if p == 1 16 | end 17 | 18 | def method_missing(method, *args) 19 | JSON.parse(self.class.get "/data", :query => {:act => method, :id => @id, :sid => VK::Auth.sid}) 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.dirname(__FILE__)) 2 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) 3 | 4 | require 'rubygems' 5 | require 'webmock/rspec' 6 | 7 | require 'userapi' 8 | 9 | include WebMock 10 | -------------------------------------------------------------------------------- /spec/userapi/auth_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') 2 | 3 | describe VK::Auth do 4 | context "with valid email and password" do 5 | before do 6 | stub_request(:any, 'login.userapi.com/auth').with(:query => { 7 | "site" => "2", 8 | "pass" => "password", 9 | "login" => "force", 10 | "email" => "test@test.com"}).to_return(:headers => { 11 | "Location" => ";sid=123", 12 | "Set-Cookie" => "remixmid=123"}, 13 | :status => 302) 14 | end 15 | 16 | it 'should #login! properly' do 17 | VK::Auth.login!("test@test.com", "password").should be(true) 18 | end 19 | 20 | context "should return proper" do 21 | before do 22 | VK::Auth.login!("test@test.com", "password") 23 | end 24 | 25 | it '#sid' do 26 | VK::Auth.sid.should eql "123" 27 | end 28 | 29 | it '#user_id' do 30 | VK::Auth.user_id.should eql "123" 31 | end 32 | end 33 | end 34 | 35 | context "with invalid email and password" do 36 | before do 37 | stub_request(:any, 'login.userapi.com/auth').with(:query => { 38 | "site" => "2", 39 | "pass" => "password", 40 | "login" => "force", 41 | "email" => "test@test.com"}) 42 | end 43 | 44 | it "should error an exception" do 45 | lambda { VK::Auth.login!("test@test.com", "password") }.should raise_error(VK::AuthFail) 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /spec/userapi/user_spec.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') 2 | 3 | describe VK::User do 4 | before do 5 | @user = VK::User.new "1" 6 | end 7 | 8 | subject {@user.id} 9 | it {should eql 1} 10 | 11 | context "#friends" do 12 | it 'should return an Array' do 13 | @user.friends.should_be_instance_of Array 14 | end 15 | 16 | it 'should return only part of friends array with :to and :from paramaters' 17 | it 'should skip some elements if only :from paramater present' 18 | it 'should not return some last elements if only :to paramter present' 19 | end 20 | 21 | context "#friends_mutal" do 22 | it 'should return an Array' do 23 | @user.friends.should_be_instance_of Array 24 | end 25 | 26 | it 'should return only part of mutal friends array with :to and :from paramaters' 27 | it 'should skip some elements if only :from paramater present' 28 | it 'should not return some last elements if only :to paramter present' 29 | end 30 | 31 | context "#friends_online" do 32 | it 'should return an Array' do 33 | @user.friends_online.should_be_instance_of Array 34 | end 35 | 36 | it 'should return only part of online friends array with :to and :from paramaters' 37 | it 'should skip some elements if only :from paramater present' 38 | it 'should not return some last elements if only :to paramter present' 39 | end 40 | 41 | context "#friends_new" do 42 | it 'should return an Array' do 43 | @user.friends_new.should_be_instance_of Array 44 | end 45 | 46 | it 'should return only part of new friends array with :to and :from paramaters' 47 | it 'should skip some elements if only :from paramater present' 48 | it 'should not return some last elements if only :to paramter present' 49 | end 50 | 51 | context "#photos" do 52 | it 'should return an Array' do 53 | @user.photos.should_be_instance_of Array 54 | end 55 | 56 | it 'should return only part of photos array with :to and :from paramaters' 57 | it 'should skip some elements if only :from paramater present' 58 | it 'should not return some last elements if only :to paramter present' 59 | end 60 | 61 | context "#photos_new" do 62 | it 'should return an Array' do 63 | @user.photos_new.should_be_instance_of Array 64 | end 65 | 66 | it 'should return only part of photos array with :to and :from paramaters' 67 | it 'should skip some elements if only :from paramater present' 68 | it 'should not return some last elements if only :to paramter present' 69 | end 70 | 71 | context "#photos_with" do 72 | it 'should return an Array' do 73 | @user.photos_with.should_be_instance_of Array 74 | end 75 | 76 | it 'should return only part of photos array with :to and :from paramaters' 77 | it 'should skip some elements if only :from paramater present' 78 | it 'should not return some last elements if only :to paramter present' 79 | end 80 | end 81 | 82 | # TODO: Extract in own file 83 | describe VK::User::Wall do 84 | before do 85 | @user = VK::User.new "1" 86 | end 87 | 88 | it 'should be a Singleton class' 89 | 90 | subject {user.wall_size} 91 | it {should eql 10} 92 | 93 | context '#wall' do 94 | it 'should return an Array' do 95 | @user.wall.should_be_instance_of Array 96 | end 97 | 98 | it 'should return an array of WallItems' do 99 | @user.wall[0].should_be_instance_of VK::User::Wall::WallItem 100 | end 101 | end 102 | end 103 | 104 | describe VK::User::Wall::WallItem do 105 | subject {@wall_item} 106 | it {should respond_to(:id)} 107 | it {should respond_to(:time)} 108 | it {should respond_to(:content)} 109 | it {should respond_to(:sender)} 110 | it {should respond_to(:recipient)} 111 | it {should respond_to(:type)} 112 | 113 | subject {@wall_item.time} 114 | it {should_be_instance of Bignum} 115 | 116 | context '#content' do 117 | it {@wall_item.content.should be_instance_of Hash} 118 | 119 | context "of 'Plain' type" do 120 | before do 121 | end 122 | 123 | it 'should have proper :text' do 124 | @wall_item.content[:text].should eql "" 125 | end 126 | end 127 | 128 | context "of 'Photo' type" do 129 | before do 130 | end 131 | end 132 | 133 | context "of 'Graffiti' type" do 134 | before do 135 | end 136 | end 137 | 138 | context "of 'Video' type" do 139 | before do 140 | end 141 | end 142 | 143 | context "of 'Audio' type" do 144 | before do 145 | end 146 | end 147 | end 148 | end 149 | --------------------------------------------------------------------------------