quandl_client 2.7.5 → 2.7.6
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.
- data/.gitignore +7 -7
- data/.rspec +1 -1
- data/.travis.yml +20 -20
- data/.yardopts +2 -2
- data/Gemfile +12 -12
- data/Guardfile +8 -8
- data/LICENSE +7 -7
- data/README.md +303 -303
- data/Rakefile +31 -35
- data/UPGRADE.md +190 -213
- data/VERSION +1 -1
- data/examples/create.rb +32 -32
- data/examples/find.rb +17 -17
- data/examples/login.rb +12 -12
- data/examples/search.rb +12 -12
- data/examples/trims.rb +15 -15
- data/lib/quandl/client.rb +49 -49
- data/lib/quandl/client/base.rb +91 -91
- data/lib/quandl/client/base/attributes.rb +15 -15
- data/lib/quandl/client/base/model.rb +40 -40
- data/lib/quandl/client/base/search.rb +74 -74
- data/lib/quandl/client/base/validation.rb +101 -101
- data/lib/quandl/client/middleware.rb +9 -9
- data/lib/quandl/client/middleware/parse_json.rb +85 -85
- data/lib/quandl/client/models/dataset.rb +261 -245
- data/lib/quandl/client/models/dataset/data.rb +57 -57
- data/lib/quandl/client/models/location.rb +10 -10
- data/lib/quandl/client/models/report.rb +14 -14
- data/lib/quandl/client/models/scraper.rb +16 -16
- data/lib/quandl/client/models/sheet.rb +50 -50
- data/lib/quandl/client/models/source.rb +48 -40
- data/lib/quandl/client/models/superset.rb +59 -59
- data/lib/quandl/client/models/user.rb +7 -7
- data/lib/quandl/client/version.rb +14 -14
- data/lib/quandl/her/remove_method_data.rb +8 -8
- data/lib/quandl/pattern.rb +37 -37
- data/lib/quandl/pattern/client.rb +8 -8
- data/quandl_client.gemspec +33 -33
- data/spec/factories/dataset.rb +10 -10
- data/spec/factories/sheet.rb +7 -7
- data/spec/factories/source.rb +9 -9
- data/spec/fixtures/scraper.rb +5 -5
- data/spec/lib/quandl/client/dataset/attributes_spec.rb +63 -63
- data/spec/lib/quandl/client/dataset/data_spec.rb +92 -92
- data/spec/lib/quandl/client/dataset/location_spec.rb +65 -65
- data/spec/lib/quandl/client/dataset/persistence_spec.rb +104 -104
- data/spec/lib/quandl/client/dataset/search_spec.rb +19 -19
- data/spec/lib/quandl/client/dataset/source_spec.rb +47 -47
- data/spec/lib/quandl/client/dataset/trim_spec.rb +35 -35
- data/spec/lib/quandl/client/dataset/validation_spec.rb +68 -68
- data/spec/lib/quandl/client/dataset_spec.rb +57 -57
- data/spec/lib/quandl/client/scraper_spec.rb +71 -71
- data/spec/lib/quandl/client/sheet_spec.rb +37 -37
- data/spec/lib/quandl/client/source_spec.rb +51 -51
- data/spec/spec_helper.rb +30 -30
- metadata +27 -5
@@ -1,16 +1,16 @@
|
|
1
|
-
class Quandl::Client::Base
|
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
|
14
|
-
|
15
|
-
end
|
1
|
+
class Quandl::Client::Base
|
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
|
14
|
+
|
15
|
+
end
|
16
16
|
end
|
@@ -1,41 +1,41 @@
|
|
1
|
-
class Quandl::Client::Base
|
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
|
39
|
-
|
40
|
-
end
|
1
|
+
class Quandl::Client::Base
|
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
|
39
|
+
|
40
|
+
end
|
41
41
|
end
|
@@ -1,75 +1,75 @@
|
|
1
|
-
class Quandl::Client::Base
|
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) }
|
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)
|
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
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
1
|
+
class Quandl::Client::Base
|
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) }
|
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)
|
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
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
75
|
end
|
@@ -1,102 +1,102 @@
|
|
1
|
-
class Quandl::Client::Base
|
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
|
18
|
-
end
|
19
|
-
true
|
20
|
-
end
|
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
|
-
Quandl::Client::HTTP_STATUS_CODES[status]
|
48
|
-
end
|
49
|
-
|
50
|
-
def status
|
51
|
-
metadata[:status].to_i
|
52
|
-
end
|
53
|
-
|
54
|
-
def human_error_messages
|
55
|
-
return if errors.blank?
|
56
|
-
m = "#{status}\n"
|
57
|
-
m += " errors: \n"
|
58
|
-
m += error_messages.collect do |error_type, messages|
|
59
|
-
next human_error_message(error_type, messages) unless messages.is_a?(Hash)
|
60
|
-
messages.collect{|n,m| human_error_message(n, m) }
|
61
|
-
end.flatten.compact.join
|
62
|
-
end
|
63
|
-
|
64
|
-
def error_messages
|
65
|
-
valid?
|
66
|
-
errors.messages
|
67
|
-
end
|
68
|
-
|
69
|
-
def errors
|
70
|
-
apply_response_errors
|
71
|
-
super
|
72
|
-
end
|
73
|
-
|
74
|
-
def human_error_message(name, message)
|
75
|
-
message = message.join(', ') if message.respond_to?(:join)
|
76
|
-
" #{name}: #{message}\n"
|
77
|
-
end
|
78
|
-
|
79
|
-
protected
|
80
|
-
|
81
|
-
def halt_unless_valid!
|
82
|
-
return false unless valid?
|
83
|
-
end
|
84
|
-
|
85
|
-
class UrlValidator < ActiveModel::EachValidator
|
86
|
-
def validate_each(record, attribute, value)
|
87
|
-
begin
|
88
|
-
uri = URI.parse(value)
|
89
|
-
resp = uri.kind_of?(URI::HTTP)
|
90
|
-
|
91
|
-
rescue URI::InvalidURIError
|
92
|
-
resp = false
|
93
|
-
end
|
94
|
-
unless resp == true
|
95
|
-
record.errors[attribute] << (options[:message] || "is not an url")
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
101
|
-
end
|
1
|
+
class Quandl::Client::Base
|
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
|
18
|
+
end
|
19
|
+
true
|
20
|
+
end
|
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
|
+
Quandl::Client::HTTP_STATUS_CODES[status]
|
48
|
+
end
|
49
|
+
|
50
|
+
def status
|
51
|
+
metadata[:status].to_i
|
52
|
+
end
|
53
|
+
|
54
|
+
def human_error_messages
|
55
|
+
return if errors.blank?
|
56
|
+
m = "#{status}\n"
|
57
|
+
m += " errors: \n"
|
58
|
+
m += error_messages.collect do |error_type, messages|
|
59
|
+
next human_error_message(error_type, messages) unless messages.is_a?(Hash)
|
60
|
+
messages.collect{|n,m| human_error_message(n, m) }
|
61
|
+
end.flatten.compact.join
|
62
|
+
end
|
63
|
+
|
64
|
+
def error_messages
|
65
|
+
valid?
|
66
|
+
errors.messages
|
67
|
+
end
|
68
|
+
|
69
|
+
def errors
|
70
|
+
apply_response_errors
|
71
|
+
super
|
72
|
+
end
|
73
|
+
|
74
|
+
def human_error_message(name, message)
|
75
|
+
message = message.join(', ') if message.respond_to?(:join)
|
76
|
+
" #{name}: #{message}\n"
|
77
|
+
end
|
78
|
+
|
79
|
+
protected
|
80
|
+
|
81
|
+
def halt_unless_valid!
|
82
|
+
return false unless valid?
|
83
|
+
end
|
84
|
+
|
85
|
+
class UrlValidator < ActiveModel::EachValidator
|
86
|
+
def validate_each(record, attribute, value)
|
87
|
+
begin
|
88
|
+
uri = URI.parse(value)
|
89
|
+
resp = uri.kind_of?(URI::HTTP)
|
90
|
+
|
91
|
+
rescue URI::InvalidURIError
|
92
|
+
resp = false
|
93
|
+
end
|
94
|
+
unless resp == true
|
95
|
+
record.errors[attribute] << (options[:message] || "is not an url")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
end
|
102
102
|
end
|