vk 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+