quandl_client 2.10.2 → 2.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/UPGRADE.md +3 -19
- data/lib/quandl/client/base.rb +1 -1
- data/lib/quandl/client/base/attributes.rb +12 -12
- data/lib/quandl/client/base/benchmark.rb +39 -39
- data/lib/quandl/client/base/model.rb +37 -37
- data/lib/quandl/client/base/search.rb +67 -68
- data/lib/quandl/client/base/validation.rb +96 -96
- data/lib/quandl/client/middleware.rb +4 -4
- data/lib/quandl/client/middleware/parse_json.rb +77 -79
- data/lib/quandl/client/models/dataset/benchmark.rb +7 -8
- data/lib/quandl/client/models/dataset/validations.rb +121 -121
- data/lib/quandl/client/models/location.rb +5 -7
- data/lib/quandl/client/models/report.rb +9 -11
- data/lib/quandl/client/models/scraper.rb +15 -18
- data/lib/quandl/client/models/sheet.rb +46 -48
- data/lib/quandl/client/models/source.rb +43 -45
- data/lib/quandl/client/version.rb +11 -11
- data/lib/quandl/pattern.rb +32 -32
- data/lib/quandl/pattern/client.rb +7 -7
- data/quandl_client.gemspec +1 -1
- data/spec/config/quandl.rb +4 -4
- data/spec/lib/quandl/client/base_spec.rb +8 -0
- data/spec/lib/quandl/client/dataset_spec.rb +4 -4
- metadata +41 -74
- data/VERSION +0 -1
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 0e6397af59de816dcbf7136472250b2c648868ef
|
4
|
+
data.tar.gz: 82c866c02e60df48f429af686ed9afd6a98c8581
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8b4439f2b297bfd7ce10e00d3c532f8db7ca9bc5a86d2911d928e748f44feee6f804df9a63c770a80e8be251773e50107bf6d2047c40ca74974654897240b778
|
7
|
+
data.tar.gz: bb964c37c4f2e941b1efe8bfc990e3cadfe1e10529e929e7e6643512618f18810e6439a5b69247e1fdb294bf8a289255130e468818d137e32a40ab68b1b28cf5
|
data/UPGRADE.md
CHANGED
@@ -1,39 +1,23 @@
|
|
1
|
-
## 2.
|
2
|
-
|
3
|
-
|
1
|
+
## 2.11.0
|
4
2
|
|
3
|
+
* Default URL includes www subdomain and HTTPS
|
5
4
|
|
5
|
+
## 2.10.2
|
6
6
|
|
7
7
|
## 2.10.1
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
9
|
## 2.10.0
|
14
10
|
|
15
11
|
* add Quandl::Client::Job
|
16
12
|
|
17
|
-
|
18
|
-
|
19
13
|
## 2.9.0
|
20
14
|
|
21
15
|
* QUGC-189 bump data
|
22
16
|
|
23
|
-
|
24
|
-
|
25
17
|
## 2.8.0
|
26
18
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
19
|
## 2.7.12
|
32
20
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
21
|
## 2.7.10
|
38
22
|
* QUGC-168 can pass request_platform
|
39
23
|
|
data/lib/quandl/client/base.rb
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
class Quandl::Client::Base
|
2
|
-
module Attributes
|
3
|
-
|
4
|
-
|
2
|
+
module Attributes
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
def write_attribute(attribute, value)
|
7
|
+
self.send(:"#{attribute}_will_change!") if @attributes[:"#{attribute}"] != value
|
8
|
+
@attributes[:"#{attribute}"] = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def read_attribute(attribute)
|
12
|
+
@attributes[:"#{attribute}"]
|
13
|
+
end
|
5
14
|
|
6
|
-
def write_attribute(attribute, value)
|
7
|
-
self.send(:"#{attribute}_will_change!") if @attributes[:"#{attribute}"] != value
|
8
|
-
@attributes[:"#{attribute}"] = value
|
9
|
-
end
|
10
|
-
|
11
|
-
def read_attribute(attribute)
|
12
|
-
@attributes[:"#{attribute}"]
|
13
15
|
end
|
14
|
-
|
15
|
-
end
|
16
16
|
end
|
@@ -1,46 +1,46 @@
|
|
1
1
|
class Quandl::Client::Base
|
2
|
-
module Benchmark
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
module ClassMethods
|
11
|
-
def benchmark(*names)
|
12
|
-
names.each do |name|
|
13
|
-
def_benchmark(name)
|
14
|
-
end
|
2
|
+
module Benchmark
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
benchmark(:save)
|
15
8
|
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
def benchmark(*names)
|
12
|
+
names.each do |name|
|
13
|
+
def_benchmark(name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def def_benchmark(name)
|
20
|
+
define_method(name) do |*args, &block|
|
21
|
+
benchmark(name) do
|
22
|
+
super(*args, &block) if defined?(super)
|
23
|
+
end
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
27
|
+
|
28
|
+
def human_benchmarks
|
29
|
+
benchmarks.sort_by{|k,v| v }.reverse.collect{|k,v| "#{k}: #{v.microseconds}ms" }.join(' | ')
|
30
|
+
end
|
31
|
+
|
32
|
+
def benchmarks
|
33
|
+
@benchmarks ||= {}
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def benchmark(name, &block)
|
39
|
+
timer = Time.now
|
40
|
+
result = block.call
|
41
|
+
self.benchmarks[name.to_sym] ||= timer.elapsed
|
42
|
+
result
|
43
|
+
end
|
44
|
+
|
26
45
|
end
|
27
|
-
|
28
|
-
def human_benchmarks
|
29
|
-
benchmarks.sort_by{|k,v| v }.reverse.collect{|k,v| "#{k}: #{v.microseconds}ms" }.join(' | ')
|
30
|
-
end
|
31
|
-
|
32
|
-
def benchmarks
|
33
|
-
@benchmarks ||= {}
|
34
|
-
end
|
35
|
-
|
36
|
-
private
|
37
|
-
|
38
|
-
def benchmark(name, &block)
|
39
|
-
timer = Time.now
|
40
|
-
result = block.call
|
41
|
-
self.benchmarks[name.to_sym] ||= timer.elapsed
|
42
|
-
result
|
43
|
-
end
|
44
|
-
|
45
|
-
end
|
46
46
|
end
|
@@ -1,41 +1,41 @@
|
|
1
1
|
class Quandl::Client::Base
|
2
|
-
module Model
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
2
|
+
module Model
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
|
8
|
+
include Her::Model
|
9
|
+
use_api Quandl::Client::Base.her_api
|
10
|
+
|
11
|
+
before_save :touch_request_started_at
|
12
|
+
after_save :touch_request_finished_at
|
13
|
+
|
14
|
+
before_destroy :touch_request_started_at
|
15
|
+
after_destroy :touch_request_finished_at
|
16
|
+
|
17
|
+
attr_accessor :request_started_at, :request_finished_at
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def elapsed_request_time_ms
|
22
|
+
elapsed_request_time.to_f.microseconds.to_s + 'ms'
|
23
|
+
end
|
24
|
+
|
25
|
+
def elapsed_request_time
|
26
|
+
return nil unless request_finished_at.is_a?(Time) && request_started_at.is_a?(Time)
|
27
|
+
@elapsed_request_time ||= (request_finished_at - request_started_at)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def touch_request_started_at
|
33
|
+
self.request_started_at = Time.now
|
34
|
+
end
|
35
|
+
|
36
|
+
def touch_request_finished_at
|
37
|
+
self.request_finished_at = Time.now
|
38
|
+
end
|
29
39
|
|
30
|
-
private
|
31
|
-
|
32
|
-
def touch_request_started_at
|
33
|
-
self.request_started_at = Time.now
|
34
|
-
end
|
35
|
-
|
36
|
-
def touch_request_finished_at
|
37
|
-
self.request_finished_at = Time.now
|
38
40
|
end
|
39
|
-
|
40
|
-
end
|
41
41
|
end
|
@@ -1,75 +1,74 @@
|
|
1
1
|
class Quandl::Client::Base
|
2
|
-
module Search
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
included do
|
14
|
-
|
15
|
-
include ScopeComposer::Model
|
16
|
-
|
17
|
-
has_scope_composer
|
18
|
-
|
19
|
-
scope :limit
|
20
|
-
scope :with_id, ->(value) { where( id: value.to_i )}
|
21
|
-
scope_helper :all, ->{ connection.where(attributes_with_scopes).fetch }
|
22
|
-
scope_helper :connection, -> { self.class.parent }
|
23
|
-
|
24
|
-
scope.class_eval do
|
25
|
-
|
26
|
-
delegate *Array.forwardable_methods.reject{|m| [:find, :fetch].include?(m) }, to: :all
|
27
|
-
|
28
|
-
def fetch_once
|
29
|
-
@fetch_once ||= fetch
|
30
|
-
end
|
31
|
-
|
32
|
-
def fetch
|
33
|
-
find(attributes_with_scopes[:id])
|
34
|
-
end
|
35
|
-
|
36
|
-
def find(id)
|
37
|
-
result = self.class.parent.where( attributes_with_scopes ).find(id)
|
38
|
-
result = self.class.parent.new(id: id) if result.nil?
|
39
|
-
result
|
40
|
-
end
|
41
|
-
|
42
|
-
def attributes_with_scopes
|
43
|
-
attributes.merge(scope_attributes)
|
2
|
+
module Search
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
|
8
|
+
def forwardable_scope_methods
|
9
|
+
@forwardable_scope_methods ||= Array.forwardable_methods.reject{|m| [:find, :fetch].include?(m) }
|
44
10
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
11
|
+
end
|
12
|
+
|
13
|
+
included do
|
14
|
+
|
15
|
+
include ScopeComposer::Model
|
16
|
+
|
17
|
+
has_scope_composer
|
18
|
+
|
19
|
+
scope :limit
|
20
|
+
scope :with_id, ->(value) { where( id: value.to_i )}
|
21
|
+
scope_helper :all, ->{ connection.where(attributes_with_scopes).fetch }
|
22
|
+
scope_helper :connection, -> { self.class.parent }
|
23
|
+
|
24
|
+
scope.class_eval do
|
25
|
+
|
26
|
+
delegate *Array.forwardable_methods.reject{|m| [:find, :fetch].include?(m) }, to: :all
|
27
|
+
|
28
|
+
def fetch_once
|
29
|
+
@fetch_once ||= fetch
|
30
|
+
end
|
31
|
+
|
32
|
+
def fetch
|
33
|
+
find(attributes_with_scopes[:id])
|
60
34
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
35
|
+
|
36
|
+
def find(id)
|
37
|
+
result = self.class.parent.where( attributes_with_scopes ).find(id)
|
38
|
+
result = self.class.parent.new(id: id) if result.nil?
|
39
|
+
result
|
40
|
+
end
|
41
|
+
|
42
|
+
def attributes_with_scopes
|
43
|
+
attributes.merge(scope_attributes)
|
44
|
+
end
|
45
|
+
|
46
|
+
def each_in_page(options={}, &block)
|
47
|
+
# count
|
48
|
+
options[:count] ||= 0
|
49
|
+
options[:limit] ||= attributes[:limit]
|
50
|
+
# fetch records
|
51
|
+
records = all
|
52
|
+
# pass each record upstream
|
53
|
+
records.each do |r|
|
54
|
+
# is a limit set?
|
55
|
+
return if options[:limit].present? && options[:count] > options[:limit]
|
56
|
+
# call block
|
57
|
+
block.call( r )
|
58
|
+
# increase counter
|
59
|
+
options[:count] += 1
|
60
|
+
end
|
61
|
+
# blank array indidcates last page
|
62
|
+
return if records.blank? || records.count < records.try(:metadata).try(:[], :per_page).to_i
|
63
|
+
# next page
|
64
|
+
scope_attributes[:page] = 1 if scope_attributes[:page].blank?
|
65
|
+
scope_attributes[:page] = scope_attributes[:page].to_i + 1
|
66
|
+
# call recursively until we reach the end
|
67
|
+
each_in_page(options, &block)
|
68
|
+
end
|
69
|
+
|
68
70
|
end
|
69
|
-
|
71
|
+
|
70
72
|
end
|
71
|
-
|
72
73
|
end
|
73
|
-
end
|
74
|
-
|
75
74
|
end
|
@@ -1,104 +1,104 @@
|
|
1
1
|
class Quandl::Client::Base
|
2
|
-
module Validation
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
2
|
+
module Validation
|
3
|
+
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
|
8
|
+
before_save :halt_unless_valid!
|
9
|
+
|
10
|
+
after_save :apply_response_errors
|
11
|
+
|
12
|
+
def apply_response_errors
|
13
|
+
return unless response_errors.respond_to?(:each)
|
14
|
+
response_errors.each do |key, messages|
|
15
|
+
if messages.respond_to?(:each) && @errors.respond_to?(:add)
|
16
|
+
messages.each{|message| @errors.add(key.to_sym, message) unless @errors.has_key?(key.to_sym) }
|
17
|
+
end
|
17
18
|
end
|
19
|
+
true
|
18
20
|
end
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
resp
|
95
|
-
|
96
|
-
|
97
|
-
record.errors[attribute] << (options[:message] || "is not an url")
|
21
|
+
|
22
|
+
def save!
|
23
|
+
save
|
24
|
+
end
|
25
|
+
|
26
|
+
def blank?
|
27
|
+
!present?
|
28
|
+
end
|
29
|
+
|
30
|
+
def exists?
|
31
|
+
present?
|
32
|
+
end
|
33
|
+
|
34
|
+
def present?
|
35
|
+
status >= 200 && status < 300
|
36
|
+
end
|
37
|
+
|
38
|
+
def saved?
|
39
|
+
status >= 200 && status <= 210
|
40
|
+
end
|
41
|
+
|
42
|
+
def queried?
|
43
|
+
status > 0
|
44
|
+
end
|
45
|
+
|
46
|
+
def human_status
|
47
|
+
return 'Deleted' if metadata[:method] == :delete && status == 200
|
48
|
+
return 'Updated' if metadata[:method] == :put && status == 200
|
49
|
+
Quandl::Client::HTTP_STATUS_CODES[status]
|
50
|
+
end
|
51
|
+
|
52
|
+
def status
|
53
|
+
metadata[:status].to_i
|
54
|
+
end
|
55
|
+
|
56
|
+
def human_error_messages
|
57
|
+
return if errors.blank?
|
58
|
+
m = "#{status}\n"
|
59
|
+
m += " errors: \n"
|
60
|
+
m += error_messages.collect do |error_type, messages|
|
61
|
+
next human_error_message(error_type, messages) unless messages.is_a?(Hash)
|
62
|
+
messages.collect{|n,m| human_error_message(n, m) }
|
63
|
+
end.flatten.compact.join
|
64
|
+
end
|
65
|
+
|
66
|
+
def error_messages
|
67
|
+
valid?
|
68
|
+
errors.messages
|
69
|
+
end
|
70
|
+
|
71
|
+
def errors
|
72
|
+
apply_response_errors
|
73
|
+
super
|
74
|
+
end
|
75
|
+
|
76
|
+
def human_error_message(name, message)
|
77
|
+
message = message.join(', ') if message.respond_to?(:join)
|
78
|
+
" #{name}: #{message}\n"
|
79
|
+
end
|
80
|
+
|
81
|
+
protected
|
82
|
+
|
83
|
+
def halt_unless_valid!
|
84
|
+
return false unless valid?
|
85
|
+
end
|
86
|
+
|
87
|
+
class UrlValidator < ActiveModel::EachValidator
|
88
|
+
def validate_each(record, attribute, value)
|
89
|
+
begin
|
90
|
+
uri = URI.parse(value)
|
91
|
+
resp = uri.kind_of?(URI::HTTP)
|
92
|
+
|
93
|
+
rescue URI::InvalidURIError
|
94
|
+
resp = false
|
95
|
+
end
|
96
|
+
unless resp == true
|
97
|
+
record.errors[attribute] << (options[:message] || "is not an url")
|
98
|
+
end
|
98
99
|
end
|
99
100
|
end
|
101
|
+
|
100
102
|
end
|
101
|
-
|
102
103
|
end
|
103
|
-
end
|
104
104
|
end
|