vk 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ doc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in vk.gemspec
4
+ gemspec
@@ -0,0 +1,49 @@
1
+ # Vk: API wrapper for vk.com
2
+
3
+ Vk is a wrapper for vk.com API
4
+
5
+ ## Installation
6
+
7
+ $ gem install vk
8
+
9
+ ## Usage
10
+
11
+ ### Initialization
12
+
13
+ Vk.app_id = 12345
14
+ Vk.app_secret = 'secret'
15
+
16
+ ### Basic usage
17
+
18
+ Simple request. Docs ad {Vk::Request}
19
+
20
+ vk = Vk.request
21
+ profiles = vk.request 'getProfiles', uids: 12345
22
+ puts profiles # [{uid: 12345, first_name: 'Ivan', last_name: 'Ivanov'}]
23
+
24
+ ### Usage with DSL
25
+
26
+ View methods list at {Vk::DSL}.
27
+
28
+ Vk.dsl!
29
+ vk = Vk.request
30
+ profiles = vk.get_profiles([123, 456, 789], fields: %w('has_mobile'))
31
+ puts profiles # [{uid: 1234, ..., has_mobile: 1}]
32
+
33
+ ### Usage with object oriented DSL
34
+
35
+ Currently implemented classes: {Vk::User}, {Vk::City}, {Vk::Country}.
36
+
37
+ user = Vk::User.find 12345
38
+ user # #<Vk::User:12345 @attributes={first_name: 'Ivan', last_name: 'Ivanov', uid: 12345}>
39
+ user.first_name # 'Ivan'
40
+ user.last_name # 'Ivanov'
41
+ user.name # 'Ivan Ivanov'
42
+ user.city # #<Vk::City:1 @attributes={name: 'Moscow', cid: 1}>
43
+ user.country # #<Vk::Country:1 @attributes={name: 'Russia', cid: 1}>
44
+ user.friends # [#<Vk::User:1 @attributes={first_name: "Pavel", last_name: "Durov", uid: 1}>, ...]
45
+ user.friends.first.city # #<Vk::City:1 @attributes={name: 'Moscow', cid: 1}>
46
+
47
+ ## License
48
+
49
+ MIT License. © [Alexander Semyonov](http://al.semyonov.us/), <al@semyonov.us>, 2011
@@ -0,0 +1,28 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ begin
5
+ require 'rspec/core/rake_task'
6
+
7
+ desc 'Run specs'
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.rspec_opts = %w(--color)
10
+ t.verbose = false
11
+ end
12
+ rescue LoadError
13
+ task :spec do
14
+ abort 'install rspec to run specs ($ bundle install)'
15
+ end
16
+ end
17
+
18
+ begin
19
+ require 'yard'
20
+ require 'yard/rake/yardoc_task'
21
+
22
+ desc 'Generate documentation'
23
+ YARD::Rake::YardocTask.new(:doc)
24
+ rescue LoadError
25
+ task :doc do
26
+ abort 'install yard to generate documentation ($ bundle install)'
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ module Vk
2
+ extend self
3
+
4
+ autoload :DSL, 'vk/dsl'
5
+ autoload :Request, 'vk/request'
6
+
7
+ autoload :Base, 'vk/base'
8
+ autoload :User, 'vk/user'
9
+ autoload :City, 'vk/city'
10
+ autoload :Country, 'vk/country'
11
+
12
+ class << self
13
+ attr_accessor :app_id, :app_secret
14
+ end
15
+
16
+ def request
17
+ @request ||= Request.new
18
+ end
19
+
20
+ def dsl!
21
+ Request.dsl!
22
+ end
23
+ end
@@ -0,0 +1,90 @@
1
+ require 'vk'
2
+
3
+ require 'active_support/core_ext/class/attribute'
4
+ require 'active_support/core_ext/array/extract_options'
5
+ require 'active_support/hash_with_indifferent_access'
6
+
7
+ module Vk
8
+ dsl! # require DSL methods in Vk::Request
9
+
10
+ class Base
11
+ class_attribute :identity_map, :loader, :key_field, :fields
12
+ self.loader = Vk.request
13
+
14
+ class << self
15
+ # Find object in identity map or initialize object
16
+ def find(*ids)
17
+ options = ids.extract_options!
18
+ if ids.count == 1
19
+ id = ids.first.to_i
20
+ identity_map[id] ||= new(id, options)
21
+ elsif respond_to?(:find_all)
22
+ find_all(ids, options)
23
+ else
24
+ ids.map do |id|
25
+ find(id, options)
26
+ end
27
+ end
28
+ end
29
+
30
+ def method_missing(method, *args)
31
+ if identity_map.respond_to?(method)
32
+ identity_map.send(method, *args)
33
+ else
34
+ super
35
+ end
36
+ end
37
+
38
+ def inherited(subclass)
39
+ subclass.identity_map = {}
40
+ subclass.fields = []
41
+ end
42
+ end
43
+
44
+ def initialize(id, options = {})
45
+ @attributes = ActiveSupport::HashWithIndifferentAccess.new
46
+
47
+ self.id = id
48
+ self.class.identity_map[id] = self
49
+
50
+ if options.key? :data
51
+ @attributes.merge!(options[:data])
52
+ else
53
+ load_data(options)
54
+ end
55
+ end
56
+
57
+ def id=(id)
58
+ @attributes[key_field] = id
59
+ end
60
+
61
+ def id
62
+ @attributes[key_field]
63
+ end
64
+
65
+ def read_attribute(name)
66
+ if !@attributes.key?(name) && fields.include?(name.to_sym)
67
+ load_data(fields: name)
68
+ end
69
+ @attributes[name]
70
+ end
71
+
72
+ def method_missing(method, *args)
73
+ if @attributes.key?(method)
74
+ @attributes[method.to_s]
75
+ else
76
+ super
77
+ end
78
+ end
79
+
80
+ def inspect
81
+ "#<#{self.class.name}:#{id} @attributes=#{@attributes.inspect}>"
82
+ end
83
+
84
+ protected
85
+
86
+ def load_data(options = {})
87
+ raise 'Not implemented. Use subclasses'
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,18 @@
1
+ require 'vk/base'
2
+
3
+ module Vk
4
+ class City < Base
5
+ self.key_field = :cid
6
+ self.fields = [:cid, :name]
7
+
8
+ def to_s
9
+ name
10
+ end
11
+
12
+ protected
13
+
14
+ def load_data(options = {})
15
+ @attributes = @attributes.merge(loader.get_city(id))
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ require 'vk/base'
2
+
3
+ module Vk
4
+ class Country < Base
5
+ self.key_field = :cid
6
+ self.fields = [:cid, :name]
7
+
8
+ def to_s
9
+ name
10
+ end
11
+
12
+ protected
13
+
14
+ def load_data(options = {})
15
+ @attributes = @attributes.merge(loader.get_country(id))
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,86 @@
1
+ # coding: utf-8
2
+ require 'vk'
3
+
4
+ module Vk
5
+ module DSL
6
+ # Have user installed app?
7
+ # @param [String] uid user’s identifier
8
+ # @return [Boolean] does user installed app
9
+ def app_user?(uid)
10
+ request('isAppUser', uid: uid) == '1'
11
+ end
12
+
13
+ # Profile information for provided uids or domain names
14
+ # @param [Array<String>] uids array of users’ identifiers in numbers or domain names
15
+ # @param [Hash] options the options to request profile information
16
+ # @option options [:uid, :first_name, :last_name, :nickname, :domain, :sex, :bdate, :birthdate, :city, :country, :timezone, :photo, :photo_medium, :photo_big, :has_mobile, :rate, :contacts, :education, :online] :fields ([:uid, :first_name, :last_name]) profile fields to requests
17
+ # @option options [:nom, :gen, :dat, :acc, :ins, :abl] :name_case (:nom) case of returned names
18
+ # @return [Array<Hash>] array of user profile data
19
+ def get_profiles(uids, options = {})
20
+ uids = Array(uids)
21
+ if uids.first.to_i == 0
22
+ options[:domains] = uids.join ','
23
+ else
24
+ options[:uids] = uids.join ','
25
+ end
26
+ options[:fields] = Array(options[:fields]).join(',') if options.key?(:fields)
27
+ request('getProfiles', options)
28
+ end
29
+
30
+ def get_profile(uid, options = {})
31
+ get_profiles(uid, options)[0]
32
+ end
33
+
34
+ ## Identifiers of groups in which user participates
35
+ ## @param [Integer] uid user’s identifier
36
+ ## @return [Array] array of group identifiers
37
+ #def get_groups(uid)
38
+ #request('getGroups', uid: uid)
39
+ #end
40
+
41
+ # Cities’ names
42
+ # @param [Array<Fixnum>, Fixnum] cids cities identifiers
43
+ # @return [Array<Hash>] hash with city identifier and it’s name
44
+ def get_cities(cids)
45
+ cids = Array(cids).join(',')
46
+ request('getCities', cids: cids)
47
+ end
48
+
49
+ def get_city(cid)
50
+ get_cities(cid)[0]
51
+ end
52
+
53
+ # Countries’ names
54
+ # @param [Array<Fixnum>, Fixnum] cids cities identifiers
55
+ # @return [Array<Hash>] hash with city identifier and it’s name
56
+ def get_countries(cids)
57
+ cids = Array(cids).join(',')
58
+ request('getCountries', cids: cids)
59
+ end
60
+
61
+ def get_country(cid)
62
+ get_countries(cid)[0]
63
+ end
64
+
65
+ # Friends information
66
+ # @param [Fixnum] uid user identifier
67
+ # @param [Hash] options
68
+ # @option options [Array<String>] :fields ([:uid, :first_name, :last_name]) what fields to request
69
+ # @option options [Fixnum] :count how many friends to request
70
+ # @option options [Fixnum] :offset offset of friends to request
71
+ def get_friends(uid, options = {})
72
+ request('friends.get', options.merge(uid: uid))
73
+ end
74
+
75
+ # Statuses from user’s wall
76
+ # @param [Fixnum] uid user identifier
77
+ # @param [Hash] options
78
+ # @option options [Fixnum] :count how many statuses to request
79
+ # @option options [Fixnum] :offset offset of statuses to request
80
+ # @option options [:owner, :others, :all] :filter (:all) what kind of statuses to request
81
+ # @return [Array<Fixnum, *Hash>] count of statuses and each status in hash
82
+ def get_wall(uid, options = {})
83
+ request('wall.get', options.merge(owner_id: uid))
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,64 @@
1
+ # coding: utf-8
2
+ require 'vk'
3
+
4
+ require 'digest/md5'
5
+ require 'uri'
6
+ require 'net/http'
7
+
8
+ require 'active_support/core_ext/object/to_query'
9
+ require 'json'
10
+
11
+ module Vk
12
+ # Class for requesting vk.com api data
13
+ # @author Alexander Semyonov
14
+ class Request
15
+ VERSION = '3.0'
16
+ SCHEME = 'http'
17
+ HOST = 'api.vk.com'
18
+ PATH = '/api.php'
19
+ PORT = 80
20
+
21
+ class << self
22
+ # Generates auth_key for viewer
23
+ # @param [Fixnum, String] viewer_id viewer’s identifier
24
+ def auth_key(viewer_id)
25
+ Digest::MD5.hexdigest("#{Vk.app_id}_#{viewer_id}_#{Vk.app_secret}")
26
+ end
27
+
28
+ def authenticated?(viewer_id, auth_key)
29
+ auth_key == self.auth_key(viewer_id)
30
+ end
31
+
32
+ def dsl!
33
+ require 'vk/dsl'
34
+ include Vk::DSL
35
+ end
36
+ end
37
+
38
+ def request(method_name, data = {})
39
+ data.merge!(
40
+ api_id: Vk.app_id,
41
+ format: :json,
42
+ method: method_name,
43
+ v: VERSION
44
+ )
45
+ url = URI.parse("#{SCHEME}://#{HOST}:#{PORT}#{PATH}?#{data.to_query}&sig=#{signature(data)}")
46
+ http_response = Net::HTTP.get_response(url).body
47
+ json_response = JSON.parse(http_response)
48
+ puts(json_response)
49
+ json_response['response']
50
+ end
51
+
52
+
53
+ def method_missing(method_name, options = {})
54
+ request(method_name, options)
55
+ end
56
+
57
+ private
58
+
59
+ def signature(data)
60
+ signature = data.keys.sort.inject('') { |result, key| result << "#{key}=#{data[key]}" } << Vk.app_secret
61
+ Digest::MD5.hexdigest(signature)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,59 @@
1
+ require 'vk/base'
2
+
3
+ module Vk
4
+ class User < Base
5
+ self.key_field = :uid
6
+ self.fields = [:uid, :first_name, :last_name, :nickname, :domain, :sex, :bdate, :birthdate, :city, :country, :timezone, :photo, :photo_medium, :photo_big, :has_mobile, :rate, :contacts, :education, :online]
7
+
8
+ class << self
9
+ def find_all(ids, options = {})
10
+ loaded_ids = ids & identity_map.keys
11
+ ids_to_load = ids - loaded_ids
12
+ identity_map.values_at(*loaded_ids).tap do |results|
13
+ if ids_to_load.any?
14
+ results << loader.get_profiles(ids - loaded_ids, options).map do |profile|
15
+ new(profile['uid'], data: profile)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ def name
23
+ "#{first_name} #{last_name}"
24
+ end
25
+
26
+ def city_id
27
+ read_attribute(:city)
28
+ end
29
+
30
+ def city
31
+ Vk::City.find(city_id)
32
+ end
33
+
34
+ def country_id
35
+ read_attribute(:country)
36
+ end
37
+
38
+ def country
39
+ Vk::Country.find(country_id)
40
+ end
41
+
42
+ def friend_ids
43
+ @friend_ids ||= loader.get_friends(uid)
44
+ end
45
+
46
+ def friends(options = {})
47
+ @friends ||= User.find_all(friend_ids, options)
48
+ end
49
+
50
+ def to_s
51
+ name
52
+ end
53
+
54
+ protected
55
+ def load_data(options = {})
56
+ @attributes = @attributes.merge(loader.get_profile(id, options))
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,3 @@
1
+ module Vk
2
+ VERSION = '0.0.2'
3
+ end
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+ require 'vk'
4
+
5
+ Bundler.require(:development)
6
+
7
+ Vk.app_id = 2311992
8
+ Vk.app_secret = 'secret'
9
+
10
+ VK_AUTH_KEY = '44b0a08fcf4039bf7919132a777b23ef'
11
+ VK_VIEWER_ID = 34160
12
+
13
+ RSpec.configure do |config|
14
+ config.mock_with :rspec
15
+ end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Vk::Request do
4
+ describe 'class' do
5
+ subject { Vk::Request }
6
+
7
+ it { should respond_to(:auth_key) }
8
+ it { should respond_to(:authenticated?) }
9
+ it { Vk::Request.auth_key(VK_VIEWER_ID).should == VK_AUTH_KEY }
10
+ it { Vk::Request.authenticated?(VK_VIEWER_ID, VK_AUTH_KEY).should be_true }
11
+ end
12
+
13
+ describe 'instance' do
14
+ let(:request) { Vk::Request.new }
15
+ subject { request }
16
+
17
+ it { should respond_to(:request) }
18
+ end
19
+ end
@@ -0,0 +1,5 @@
1
+ require 'spec_helper'
2
+
3
+ describe Vk do
4
+ it { should respond_to(:request) }
5
+ end
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'vk/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'vk'
7
+ s.version = Vk::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ['Alexander Semyonov']
10
+ s.email = ['al@semyonov.us']
11
+ s.homepage = 'http://github.com/alsemyonov/vk'
12
+ s.summary = %q{Simple wrapper for vk.com API}
13
+ s.description = %q{Wrapper for calling vk.com API from vk.com application servers and sites using vk.com API}
14
+
15
+ s.rubyforge_project = 'vk'
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ['lib']
21
+
22
+ s.add_dependency('activesupport', '~> 3.0')
23
+ s.add_dependency('json', '~> 1.5.1')
24
+
25
+ s.add_development_dependency('rspec', '~> 2.5.0')
26
+ s.add_development_dependency('yard', '~> 0.6.8')
27
+ end
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vk
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - Alexander Semyonov
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-05-03 00:00:00 +06:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activesupport
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 3
30
+ - 0
31
+ version: "3.0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: json
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 1
44
+ - 5
45
+ - 1
46
+ version: 1.5.1
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ~>
56
+ - !ruby/object:Gem::Version
57
+ segments:
58
+ - 2
59
+ - 5
60
+ - 0
61
+ version: 2.5.0
62
+ type: :development
63
+ version_requirements: *id003
64
+ - !ruby/object:Gem::Dependency
65
+ name: yard
66
+ prerelease: false
67
+ requirement: &id004 !ruby/object:Gem::Requirement
68
+ none: false
69
+ requirements:
70
+ - - ~>
71
+ - !ruby/object:Gem::Version
72
+ segments:
73
+ - 0
74
+ - 6
75
+ - 8
76
+ version: 0.6.8
77
+ type: :development
78
+ version_requirements: *id004
79
+ description: Wrapper for calling vk.com API from vk.com application servers and sites using vk.com API
80
+ email:
81
+ - al@semyonov.us
82
+ executables: []
83
+
84
+ extensions: []
85
+
86
+ extra_rdoc_files: []
87
+
88
+ files:
89
+ - .gitignore
90
+ - Gemfile
91
+ - README.markdown
92
+ - Rakefile
93
+ - lib/vk.rb
94
+ - lib/vk/base.rb
95
+ - lib/vk/city.rb
96
+ - lib/vk/country.rb
97
+ - lib/vk/dsl.rb
98
+ - lib/vk/request.rb
99
+ - lib/vk/user.rb
100
+ - lib/vk/version.rb
101
+ - spec/spec_helper.rb
102
+ - spec/vk/request_spec.rb
103
+ - spec/vk_spec.rb
104
+ - vk.gemspec
105
+ has_rdoc: true
106
+ homepage: http://github.com/alsemyonov/vk
107
+ licenses: []
108
+
109
+ post_install_message:
110
+ rdoc_options: []
111
+
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ segments:
120
+ - 0
121
+ version: "0"
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ segments:
128
+ - 0
129
+ version: "0"
130
+ requirements: []
131
+
132
+ rubyforge_project: vk
133
+ rubygems_version: 1.3.7
134
+ signing_key:
135
+ specification_version: 3
136
+ summary: Simple wrapper for vk.com API
137
+ test_files: []
138
+