rhack 1.3.8 → 1.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 255f778be8172b77886bc90969871994f99e05b3
4
- data.tar.gz: 99653ac463971ce0f8ceec23a6c829f4c70140a8
3
+ metadata.gz: 3a6f9fd958d14ef221d1f20ebb4217decff1a257
4
+ data.tar.gz: 9b0d6cdf7cbe66b9d0f7ee3fa155761af34584c1
5
5
  SHA512:
6
- metadata.gz: 91eb7a4e415c6766830a0e4967f675b0ad472845bf03321717a30b7504b8b3034a110ec7de3301a57e589ca6d59c8c60ed09b1ca4f09e66fbc108d6b96935893
7
- data.tar.gz: 88ae5008a606ab82504206dc69b3caa7e72d4eb70108048e93634e3b9412ca8e576ad7f91c9ae3d8042b54df284bfe820eedc024f4ca122694f3abdcd6a684ff
6
+ metadata.gz: d7905168e4924ff769eb900fe57105edefa41ed98605b9421b4e9a4c1185e5ad3ce50c94034652cae9a94418f1b6fbc0da4058b153903bc91805224ba134e9ef
7
+ data.tar.gz: 2574c36ae2d5eabd0721d9134d38645963fcec1f49495642084bf63a24d1bc116cfc508564bc3c11b8e78ef212a0bc9870d9e5de30e7b7962e487136358c9339
@@ -50,7 +50,7 @@ module RHACK
50
50
  if uas = uas.desktop.to_s and File.file? uas
51
51
  @@useragents = IO.read(uas)/"\n"
52
52
  else
53
- @@useragents = ['Mozilla/5.0 (Windows NT 6.1; WOW64; rv:14.0) Gecko/20100101 Firefox/14.0.1']
53
+ @@useragents = ['Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36']
54
54
  end
55
55
 
56
56
  class Scout
@@ -58,9 +58,9 @@ module RHACK
58
58
  mattr_accessor :retry, :timeout
59
59
 
60
60
  scout = RHACK.config.scout || {}
61
- @@retry = scout.retry.b || {}
62
- @@timeout = scout.timeout.b || 60
63
- @@cacert = scout.cacert.b ? File.expand_path(scout.cacert) : File.expand_path('../../config/cacert.pem', __FILE__)
61
+ @@retry = scout.retry.presence || {}
62
+ @@timeout = scout.timeout.presence || 60
63
+ @@cacert = scout.cacert.presence ? File.expand_path(scout.cacert) : File.expand_path('../../config/cacert.pem', __FILE__)
64
64
  end
65
65
 
66
66
  end
@@ -89,5 +89,13 @@ require "rhack/scout_squad"
89
89
  require "rhack/frame"
90
90
  require "rhack/page"
91
91
  if defined? Redis::Objects
92
+ # redis storage for namespaced cache, oauth data etc
92
93
  require "rhack/storage"
93
94
  end
95
+
96
+ module RHACK
97
+ # key feature
98
+ autoload :Client, 'rhack/clients'
99
+ # basic client for oauth
100
+ autoload :OAuthClient, 'rhack/clients/oauth'
101
+ end
@@ -1,10 +1,4 @@
1
1
  require 'rhack'
2
2
  require 'rhack/clients/base'
3
3
  require 'rhack/clients/storage'
4
- require 'rhack/clients/oauth'
5
-
6
- module RHACK
7
- for name in [:Service, :ServiceError]
8
- autoload name, 'rhack/clients/compatibility'
9
- end
10
- end
4
+ require 'rhack/clients/errors'
@@ -1,29 +1,42 @@
1
1
  # encoding: utf-8
2
-
3
- # TODO 1.0+: опция для клиента, чтобы это описание имело смысл, т.к. сейчас это ложь:
4
- # Вызовам клиентов всегда следует ждут и возвращают обработанный ответ, если вызвваны без блока.
5
- # В противном случае используется событийная модель и обработанный ответ передаётся в блок.
6
2
  module RHACK
7
3
 
8
4
  class Client
9
5
  attr_reader :service
10
6
  attr_accessor :f
11
7
  class_attribute :frame_defaults, :instance_writer => false
8
+ class_attribute :scouts_initializers, :instance_writer => false
12
9
  class_attribute :accounts, :instance_writer => false
13
10
  class_attribute :routes, :instance_writer => false
14
11
  class_attribute :rootpath, :instance_writer => false
15
12
 
16
13
  self.frame_defaults = {}
14
+ self.scouts_initializers = []
17
15
  self.accounts = {}
18
16
  self.routes = {}
19
17
 
20
18
  class << self
21
19
 
22
20
  def inherited(child)
23
- child.class_eval {
21
+ child.class_eval do
24
22
  include RHACK
25
23
  __init__
26
- }
24
+
25
+ # Proxying Rails router methods digging into the client namespace
26
+ if defined? ::Rails.application.routes.url_helpers
27
+ url_helpers = ::Rails.application.routes.url_helpers
28
+ routes_namespace = name.gsub(/::/, '').underscore.sub(/_client$/, '')
29
+ route_pattern = /^(.+_)?#{routes_namespace}_(.+)/
30
+ url_helpers.my_methods.each {|name|
31
+ if name.to_s[route_pattern]
32
+ full_route_name = $&
33
+ define_method "#$1#$2" do |*options|
34
+ url_helpers.send full_route_name, *options
35
+ end
36
+ end
37
+ }
38
+ end
39
+ end
27
40
  end
28
41
 
29
42
  def method_missing(method, *args, &block)
@@ -55,8 +68,11 @@ module RHACK
55
68
  end
56
69
 
57
70
  # Set default Frame options
58
- def frame(dict)
71
+ def frame(dict, &scout_initializer)
59
72
  self.frame_defaults += dict
73
+ if scout_initializer
74
+ self.scouts_initializers << scout_initializer
75
+ end
60
76
  end
61
77
 
62
78
  # Set usable accounts
@@ -78,6 +94,13 @@ module RHACK
78
94
  if self.class.const_defined? :Result
79
95
  opts[:result] = self.class::Result
80
96
  end
97
+ if scouts_initializers = self.scouts_initializers.presence
98
+ opts[:on_scout_initialize] ||= lambda {|scout|
99
+ scouts_initializers.each {|initializer|
100
+ initializer.call scout
101
+ }
102
+ }
103
+ end
81
104
  @f = Frame(rootpath || route(service) || route(:login), opts)
82
105
  end
83
106
  end
@@ -120,7 +143,7 @@ module RHACK
120
143
  def route(name, interpolation=nil)
121
144
  if url = routes[name]
122
145
  if interpolation
123
- url %= interpolation
146
+ url %= interpolation.symbolize_keys
124
147
  end
125
148
  if url !~ /^\w+:/
126
149
  url = File.join rootpath, url
@@ -129,8 +152,6 @@ module RHACK
129
152
  end
130
153
  end
131
154
  alias :url :route
132
- # URI is deprecated # backward compatibility
133
- alias :URI :route
134
155
 
135
156
  def account(name)
136
157
  accounts[name]
@@ -138,5 +159,4 @@ module RHACK
138
159
 
139
160
  end
140
161
 
141
- class ClientError < Exception; end
142
162
  end
@@ -0,0 +1,41 @@
1
+ module RHACK
2
+
3
+ # Abstraction, don't use it.
4
+ class BasicError < StandardError
5
+ # keep here debugful data
6
+ attr_accessor :details
7
+
8
+ # # Usage ...
9
+ # # ... without :details keyword, as usual:
10
+ # raise ServerError, 'an error has occured'
11
+ # # ... with :details keyword
12
+ # raise ServerError.new 'an error has occured', details: @curl_res
13
+ # # ... if you also want to set custom backtrace
14
+ # raise ServerError.new('an error has occured', details: @curl_res), backtrace_array
15
+ def initialize(message, *opts) # details: nil
16
+ @details = opts.extract_options![:details]
17
+ super
18
+ end
19
+
20
+ end
21
+
22
+ # The client couldn't connect and yet we don't know whose this fault is,
23
+ # e.g. domain lookup error or timeout.
24
+ class ConnectionError < BasicError; end
25
+
26
+ # The client successfully connected to the server
27
+ # but it returned an improper, non-descriptive response,
28
+ # e.g. 500 status, empty body, etc.
29
+ class ServerError < BasicError; end
30
+
31
+ # The client successfully connected to the server
32
+ # but server didn't accept a request and returned a descriptive exception,
33
+ # e.g. 406 status, body with only "error" key, etc.
34
+ class RequestError < BasicError; end
35
+
36
+ # The client successfully connected to the server,
37
+ # the server accept a request but we failed to process a response,
38
+ # e.g. because of an unexpected response structure
39
+ class ClientError < BasicError; end
40
+
41
+ end
@@ -208,7 +208,7 @@ module RHACK
208
208
  df += '.map'
209
209
  text = read df
210
210
  $log << "mapfile read: #{text}"
211
- if text.b
211
+ if text.present?
212
212
  text[/^(\d+)\0+(\d+)\0*\n/]
213
213
  map = {}
214
214
  $log << [$1,$2]
@@ -25,6 +25,8 @@ module RHACK
25
25
  alias options opts
26
26
  @@cache = {}
27
27
 
28
+ # Opts passed to Scout:
29
+ # :ck / :cp, :raise, :timeout, :retry, :redir
28
30
  def initialize *args
29
31
  #args << 10 unless args[-1].is Fixnum
30
32
  #args.insert -2, {} unless args[-2].is Hash
@@ -44,6 +46,10 @@ module RHACK
44
46
  @static = false
45
47
  end
46
48
  @ss = ScoutSquad @loc.href, @opts, scouts_count
49
+ # for low-level settings that are not implemented explicitly
50
+ if @opts[:on_scout_initialize].present?
51
+ each &@opts[:on_scout_initialize]
52
+ end
47
53
  end
48
54
 
49
55
  def update_loc url
@@ -256,7 +262,7 @@ module RHACK
256
262
  order = [del ? :loadDelete : :loadGet, url]
257
263
  end
258
264
  end
259
- if !order.b and !orders.b
265
+ if order.blank? and orders.blank?
260
266
  raise ArgumentError, "failed to run blank request#{'s' if many}, params was
261
267
  (#{args.inspect[1..-2]})"
262
268
  end
@@ -20,7 +20,7 @@ module Johnson
20
20
  class << self
21
21
 
22
22
  def runtime_set?(opts)
23
- !opts[:eval].b or (@@browser and @@browser.thread_id == Curl.carier_thread.object_id)
23
+ opts[:eval].blank? or (@@browser and @@browser.thread_id == Curl.carier_thread.object_id)
24
24
  end
25
25
 
26
26
  # CarierThread breaks if Multi has no work && CarierThread
@@ -36,9 +36,9 @@ module Johnson
36
36
  unless runtime_set? opts
37
37
  if Curl.status
38
38
  Curl.recall
39
- Curl.debug 'recalled'
39
+ L.debug 'recalled'
40
40
  end
41
- if opts[:thread_safe].b
41
+ if opts[:thread_safe].present?
42
42
  @@browser = new_browser(opts[:jq])
43
43
  L.debug "#@@browser initialized in #{Thread.current}\nmain: #{Thread.main}; carier: #{Curl.carier_thread}"
44
44
  else
@@ -49,7 +49,7 @@ module RHACK
49
49
  if obj.is Curl::Easy or obj.kinda Scout
50
50
  c = obj.kinda(Scout) ? obj.http : obj
51
51
  # just (c, loc) would pass to #process opts variable that returns '' on any key
52
- process(c, loc.b || {})
52
+ process(c, loc.presence || {})
53
53
  else
54
54
  @body = obj
55
55
  @loc = loc
@@ -57,7 +57,7 @@ module RHACK
57
57
  end
58
58
 
59
59
  def empty?
60
- !@data && !@body.b
60
+ !@data && @body.blank?
61
61
  end
62
62
 
63
63
  def size
@@ -215,10 +215,10 @@ module RHACK
215
215
  document.domain = location.host;"
216
216
  find("script").each {|n|
217
217
  L.debug n.text.strip
218
- if text = n.text.strip.b
218
+ if text = n.text.strip.presence
219
219
  js[:write_output] = ''
220
220
  eval_string text
221
- if res = js[:write_output].b then n.after res end
221
+ if res = js[:write_output].presence then n.after res end
222
222
  n.remove!
223
223
  elsif frame and n.src
224
224
  eval_string frame.get_cached expand_link n.src
@@ -251,10 +251,10 @@ module RHACK
251
251
  end
252
252
 
253
253
  def title(full=true)
254
- if @data.nil? and !@failed and @body.b
254
+ if @data.nil? and !@failed and @body.present?
255
255
  if full
256
256
  to_html unless defined? @doc
257
- if @doc.title.b
257
+ if @doc.title.present?
258
258
  @title = @doc.title
259
259
  else
260
260
  @title = @loc.href
@@ -454,7 +454,7 @@ module RHACK
454
454
  if form_node['method'].downcase == 'post'
455
455
  [hash, form_node.enctype =~ /multipart/, action, opts]
456
456
  else
457
- action = "#{action}#{action['?'] ? '&' : '?'}#{hash.urlencode}" if hash.b
457
+ action = "#{action}#{action['?'] ? '&' : '?'}#{hash.urlencode}" if hash.present?
458
458
  [action, opts]
459
459
  end
460
460
  end
@@ -496,7 +496,7 @@ module RHACK
496
496
 
497
497
  def get_links(links='a')
498
498
  begin
499
- links = find(links).map {|e| e.href}.b || find(links+'//a').map {|e| e.href} if links.is String
499
+ links = find(links).map {|e| e.href}.presence || find(links+'//a').map {|e| e.href} if links.is String
500
500
  rescue LibXML::XML::Error
501
501
  links = [links]
502
502
  end
@@ -193,7 +193,7 @@ module RHACK
193
193
  when Curl::Response
194
194
  ck = res['cookies']
195
195
  end
196
- return if !ck.b
196
+ return if ck.blank?
197
197
  ck.each {|c| Cookie(c, self)}
198
198
  end
199
199
 
@@ -253,12 +253,15 @@ module RHACK
253
253
  retry!
254
254
  else
255
255
  L.debug "#{curl_err} -> not reloading scout"
256
- raise @error if @raise_err
257
- #raise *@error if @raise_err # old
258
- yield if block_given?
259
- # Now, we assume that data of this @http have been copied or will not be used anymore,
260
- # thus the scout can be reused.
261
- @busy = false
256
+ begin
257
+ raise @error if @raise_err
258
+ #raise *@error if @raise_err # old
259
+ yield if block_given?
260
+ ensure
261
+ # Now, we assume that data of this @http have been copied or will not be used anymore,
262
+ # thus the scout can be reused.
263
+ @busy = false
264
+ end
262
265
  end
263
266
  end
264
267
 
@@ -302,14 +305,17 @@ module RHACK
302
305
  process_cookies res if @cookies_enabled
303
306
  # We cannot just cancel on_complete in on_redirect block,
304
307
  # because loadGet should (and will) immediately reset on_complete back.
305
- if res.code.in(300..399) and !not_redir.b and (relvl -= 1) > -1 and loc = res.hash.location
308
+ if res.code.in(300..399) and not_redir.blank? and (relvl -= 1) > -1 and loc = res.hash.location
306
309
  loadGet(loc, headers: headers, relvl: relvl, redir: true, &callback)
307
310
  else
308
- yield @http if block_given?
309
- # Now, we assume that data of this @http have been copied or will not be used anymore,
310
- # thus the scout can be reused.
311
- @busy = false
312
- @http.on_failure &Proc::NULL
311
+ begin
312
+ yield @http if block_given?
313
+ ensure
314
+ # Now, we assume that data of this @http have been copied or will not be used anymore,
315
+ # thus the scout can be reused.
316
+ @busy = false
317
+ @http.on_failure &Proc::NULL
318
+ end
313
319
  end
314
320
  }
315
321
  # Curl::Err::* (TCP/IP level) exception callback.
@@ -353,7 +359,7 @@ module RHACK
353
359
  unless hash.is Hash # not parameterized
354
360
  opts[:headers] = opts[:headers].reverse_merge 'Content-Type' => 'application/octet-stream'
355
361
  end
356
- mkBody hash, multipart.b
362
+ mkBody hash, multipart.present?
357
363
  @last_method = :post
358
364
  if block_given?
359
365
  @post_proc = callback
@@ -62,7 +62,7 @@ module RHACK
62
62
  end
63
63
 
64
64
  def rand
65
- raise PickError if !b
65
+ raise PickError if empty?
66
66
  # to_a because Array#reject returns object of this class
67
67
  if scout = to_a.rand_by_available?
68
68
  L.debug {"randomly picked an available scout##{scout.object_id}"}
@@ -74,7 +74,7 @@ module RHACK
74
74
  end
75
75
 
76
76
  def next
77
- raise PickError if !b
77
+ raise PickError if empty?
78
78
  if scout = to_a.find_available?
79
79
  L.debug {"picked the next available scout##{scout.object_id}"}
80
80
  scout
@@ -86,7 +86,7 @@ module RHACK
86
86
 
87
87
  def to_s
88
88
  str = '<#ScoutSquad @ '
89
- if b
89
+ if any?
90
90
  if first.webproxy
91
91
  str << "#{first.proxy} ~ "
92
92
  elsif first.proxy
@@ -1,3 +1,3 @@
1
1
  module RHACK
2
- VERSION = '1.3.8'
2
+ VERSION = '1.4.0'
3
3
  end
metadata CHANGED
@@ -1,41 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rhack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.8
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergey Baev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-24 00:00:00.000000000 Z
11
+ date: 2015-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rmtools
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '2.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: libxml-ruby
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '2.7'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.7'
41
41
  description: 'RHACK is Ruby Http ACcess Kit: curl-based web-client framework created
@@ -49,7 +49,7 @@ extensions:
49
49
  - ext/curb/extconf.rb
50
50
  extra_rdoc_files: []
51
51
  files:
52
- - .gitignore
52
+ - ".gitignore"
53
53
  - CURB-LICENSE
54
54
  - Gemfile
55
55
  - LICENSE
@@ -91,6 +91,7 @@ files:
91
91
  - lib/rhack/clients.rb
92
92
  - lib/rhack/clients/base.rb
93
93
  - lib/rhack/clients/compatibility.rb
94
+ - lib/rhack/clients/errors.rb
94
95
  - lib/rhack/clients/examples.rb
95
96
  - lib/rhack/clients/oauth.rb
96
97
  - lib/rhack/clients/storage.rb
@@ -116,7 +117,6 @@ files:
116
117
  - lib/rhack/proxy/list.rb
117
118
  - lib/rhack/scout.rb
118
119
  - lib/rhack/scout_squad.rb
119
- - lib/rhack/services.rb
120
120
  - lib/rhack/storage.rb
121
121
  - lib/rhack/version.rb
122
122
  - lib/rhack_in.rb
@@ -134,19 +134,18 @@ require_paths:
134
134
  - lib
135
135
  required_ruby_version: !ruby/object:Gem::Requirement
136
136
  requirements:
137
- - - '>='
137
+ - - ">="
138
138
  - !ruby/object:Gem::Version
139
139
  version: '0'
140
140
  required_rubygems_version: !ruby/object:Gem::Requirement
141
141
  requirements:
142
- - - '>='
142
+ - - ">="
143
143
  - !ruby/object:Gem::Version
144
144
  version: '0'
145
145
  requirements: []
146
146
  rubyforge_project:
147
- rubygems_version: 2.4.1
147
+ rubygems_version: 2.2.2
148
148
  signing_key:
149
149
  specification_version: 4
150
150
  summary: Curl-based web-client framework created for developing web-scrapers/bots
151
151
  test_files: []
152
- has_rdoc:
@@ -1 +0,0 @@
1
- require 'rhack/clients'