vkontakte_client 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Vkontakte
4
+ class API
5
+ # An exception raised by `Vkontakte::API` when given a response with an error
6
+ class Error < StandardError
7
+ attr_reader :method_name, :error_code, :error_msg, :params
8
+
9
+ def initialize(method_name, error_code, error_msg, params)
10
+ @method_name = method_name
11
+ @error_code = error_code.to_i
12
+ @error_msg = error_msg
13
+ @params = params
14
+ end
15
+
16
+ # A full description of the error
17
+ def message
18
+ "VKontakte returned an error #{@error_code}: '#{@error_msg}' after calling method '#{@method_name}' with parameters #{@params.inspect}"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Vkontakte
4
+ # Ask Email and Password for user
5
+ class AskForCredentials
6
+ attr_reader :email, :password
7
+
8
+ def initialize
9
+ ask_for_credentials
10
+ end
11
+
12
+ private
13
+
14
+ def ask_for_credentials
15
+ puts 'Enter your credentials.'
16
+
17
+ print 'Email: '
18
+ @email = ask
19
+
20
+ print 'Password (typing will be hidden): '
21
+ @password = ask_for_password
22
+
23
+ nil
24
+ end
25
+
26
+ def ask
27
+ $stdin.gets.to_s.strip
28
+ end
29
+
30
+ def ask_for_password
31
+ echo_off
32
+ password = ask
33
+ puts
34
+ echo_on
35
+
36
+ password
37
+ end
38
+
39
+ def echo_off
40
+ with_tty do
41
+ system 'stty -echo'
42
+ end
43
+ end
44
+
45
+ def echo_on
46
+ with_tty do
47
+ system 'stty echo'
48
+ end
49
+ end
50
+
51
+ def with_tty
52
+ return unless $stdin.isatty
53
+
54
+ yield
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,129 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Vkontakte
4
+ # :nodoc:
5
+ class Client
6
+ attr_reader :api, :access_token, :user_id, :expires_in, :api_version
7
+
8
+ def initialize(
9
+ client_id = nil,
10
+ api_version: Vkontakte::API_VERSION,
11
+ proxy: nil,
12
+ timeout: 60
13
+ )
14
+ @client_id = client_id
15
+ @api_version = api_version
16
+ @proxy = proxy
17
+ @timeout = timeout
18
+ @authorize = false
19
+
20
+ @api = Vkontakte::API.new
21
+ end
22
+
23
+ def login!(email, pass, open_captcha: false, permissions: '')
24
+ @email = email
25
+ @pass = pass
26
+
27
+ redirect_uri = 'https://oauth.vk.com/blank.html'
28
+ display = 'mobile'
29
+ response_type = 'token'
30
+
31
+ query = {
32
+ client_id: @client_id,
33
+ redirect_uri: redirect_uri,
34
+ display: display,
35
+ scope: permissions,
36
+ response_type: response_type,
37
+ v: api_version
38
+ }
39
+
40
+ agent = Mechanize.new do |a|
41
+ a.user_agent_alias = 'Linux Firefox'
42
+ a.follow_meta_refresh
43
+
44
+ a.agent.set_socks(@proxy.addr, @proxy.port) if @proxy&.socks?
45
+ a.agent.set_proxy(@proxy.addr, @proxy.port) if @proxy&.http?
46
+ end
47
+
48
+ # https://vk.com/dev/implicit_flow_user
49
+ #
50
+ # Открытие диалога авторизации OAuth
51
+ #
52
+ query_string = query.map { |k, v| "#{k}=#{v}" }.join('&')
53
+ url = "https://oauth.vk.com/authorize?#{query_string}"
54
+
55
+ page = agent.get(url)
56
+
57
+ login_form = page.forms.first
58
+ login_form.email = @email
59
+ login_form.pass = @pass
60
+ page = login_form.submit
61
+
62
+ raise('Invalid login or password.') unless page.search('.service_msg_warning').empty?
63
+
64
+ page = submit_gain_access_form(page, open_captcha) if page.uri.path == '/authorize'
65
+
66
+ get_token(page)
67
+ end
68
+
69
+ def authorized?
70
+ @authorize ? true : false
71
+ end
72
+
73
+ private
74
+
75
+ def get_token(page)
76
+ auth_regexp = /access_token=(?<access_token>.*)&expires_in=(?<expires_in>\d+)&user_id=(?<user_id>\d*)\z/
77
+
78
+ return false unless page.uri.path == '/auth_redirect'
79
+
80
+ query_params = URI.decode_www_form(page.uri.query).to_h
81
+ authorize_url = CGI.unescape(query_params['authorize_url'])
82
+
83
+ auth_params = authorize_url.match(auth_regexp)
84
+
85
+ return false unless auth_params
86
+
87
+ @access_token = auth_params[:access_token]
88
+ @user_id = auth_params[:user_id]
89
+ @expires_in = auth_params[:expires_in]
90
+
91
+ @api = Vkontakte::API.new(
92
+ @access_token,
93
+ proxy: @proxy,
94
+ api_version: @api_version,
95
+ timeout: @timeout
96
+ )
97
+
98
+ @authorize = true
99
+
100
+ @access_token
101
+ end
102
+
103
+ def submit_gain_access_form(page, open_captcha)
104
+ form = page.forms.first
105
+
106
+ return form.submit unless form.has_key?('captcha_key')
107
+
108
+ raise('Captcha needed.') unless open_captcha
109
+
110
+ captcha_img = page.search('img[id=captcha]').first
111
+
112
+ puts 'Captcha needed.'
113
+ puts "Open url: #{captcha_img['src']}"
114
+ print 'Enter captch: '
115
+ captcha = $stdin.gets.chomp
116
+
117
+ form.pass = @pass
118
+ form.captcha_key = captcha
119
+ allow_page = form.submit
120
+
121
+ allow_form = allow_page.forms.first
122
+ allow_page = allow_form.submit if allow_form&.buttons&.detect { |btn| btn.value == 'Allow' }
123
+
124
+ raise('Invalid captcha.') unless allow_page.uri.path == '/blank.html'
125
+
126
+ allow_page
127
+ end
128
+ end
129
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Vkontakte
4
+ class Proxy # :nodoc:
5
+ attr_reader :type, :addr, :port
6
+
7
+ VALID_PROXY_TYPES = %i[http socks].freeze
8
+
9
+ def initialize(type, addr, port)
10
+ raise(StandartError, "#{`type`} is an invalid proxy type. Available values: #{VALID_PROXY_TYPES.join(',')}") unless VALID_PROXY_TYPES.include?(type)
11
+
12
+ @type = type
13
+ @addr = addr
14
+ @port = port
15
+ end
16
+
17
+ VALID_PROXY_TYPES.each do |type|
18
+ define_method(:"#{type}?") do
19
+ @type == type
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Vkontakte
4
+ VERSION = '2.0.0'
5
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'net/http'
5
+ require 'mechanize'
6
+ require 'socksify'
7
+ require 'socksify_mechanize'
8
+
9
+ require 'vkontakte/version'
10
+ require 'vkontakte/client'
11
+ require 'vkontakte/api'
12
+ require 'vkontakte/api_error'
13
+ require 'vkontakte/proxy'
14
+ require 'vkontakte/ask_for_credentials'
15
+
16
+ module Vkontakte
17
+ API_VERSION = '5.101'
18
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
4
+ require 'vkontakte/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.authors = ['Anton Maminov']
8
+ gem.email = ['anton.maminov@gmail.com']
9
+ gem.description = 'VKontakte API Client for Ruby'
10
+ gem.summary = 'Unofficial VKontakte API Client for Ruby'
11
+ gem.homepage = 'https://github.com/mamantoha/vkontakte_client'
12
+ gem.licenses = ['MIT']
13
+
14
+ gem.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
15
+ gem.files = `git ls-files`.split("\n")
16
+ gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
+ gem.name = 'vkontakte_client'
18
+ gem.require_paths = ['lib']
19
+ gem.version = Vkontakte::VERSION
20
+ gem.required_ruby_version = '>= 2.7.0'
21
+ gem.add_runtime_dependency 'mechanize', '~> 2.8', '>= 2.8.0'
22
+ gem.add_runtime_dependency 'socksify', '~> 1.7', '>= 1.7.0'
23
+ gem.add_development_dependency 'pry', '~> 0.14', '>= 0.14.0'
24
+ gem.add_development_dependency 'rubocop', '~> 1.18', '>= 1.18.0'
25
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: vkontakte_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 2.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Anton Maminov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-08-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: mechanize
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.8'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 2.8.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.8'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 2.8.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: socksify
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '1.7'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.7.0
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '1.7'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.7.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: pry
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '0.14'
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: 0.14.0
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: '0.14'
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 0.14.0
73
+ - !ruby/object:Gem::Dependency
74
+ name: rubocop
75
+ requirement: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - "~>"
78
+ - !ruby/object:Gem::Version
79
+ version: '1.18'
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 1.18.0
83
+ type: :development
84
+ prerelease: false
85
+ version_requirements: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.18'
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: 1.18.0
93
+ description: VKontakte API Client for Ruby
94
+ email:
95
+ - anton.maminov@gmail.com
96
+ executables: []
97
+ extensions: []
98
+ extra_rdoc_files: []
99
+ files:
100
+ - ".gitignore"
101
+ - ".rubocop.yml"
102
+ - LICENSE
103
+ - README.md
104
+ - README.ru.md
105
+ - examples/accept_all_requests.rb
106
+ - examples/add_suggestions.rb
107
+ - examples/ban_news_from_all_friends.rb
108
+ - examples/friends_of_friends.rb
109
+ - examples/get_online_friends.rb
110
+ - examples/last_seen.rb
111
+ - examples/long_poll.rb
112
+ - examples/mechanize.rb
113
+ - examples/remove_out_requests.rb
114
+ - examples/remove_suspended_friends.rb
115
+ - examples/users_get_offline.rb
116
+ - examples/users_info.rb
117
+ - gems.rb
118
+ - lib/socksify_mechanize.rb
119
+ - lib/vkontakte/api.rb
120
+ - lib/vkontakte/api_error.rb
121
+ - lib/vkontakte/ask_for_credentials.rb
122
+ - lib/vkontakte/client.rb
123
+ - lib/vkontakte/proxy.rb
124
+ - lib/vkontakte/version.rb
125
+ - lib/vkontakte_client.rb
126
+ - vkontakte_client.gemspec
127
+ homepage: https://github.com/mamantoha/vkontakte_client
128
+ licenses:
129
+ - MIT
130
+ metadata: {}
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: 2.7.0
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubygems_version: 3.2.22
147
+ signing_key:
148
+ specification_version: 4
149
+ summary: Unofficial VKontakte API Client for Ruby
150
+ test_files: []