quandl 0.3.4 → 0.3.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- MmU5MDQ4ZjEwNDk3MzY5ZTlmZjExNDdkMjczY2I0MmE0NzNiYmU3Ng==
4
+ N2NjNmZlMWQwNGM3ZDFiM2UwM2YwOGYxYTg4Mzk4ZjJkODQ0NzAzZA==
5
5
  data.tar.gz: !binary |-
6
- NDAxOGUzOTQ4NmIyNmIxZjZiYzIyNTk5N2JhYTlkMTNmOGYzYzhhZA==
6
+ MGM4MTU5Y2Q1ZWQyZWY4NDc4YTZkMTY0ZjMzMGUyZDAxZjM3ZDJjYw==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZWFjNTM1YmQ0NzU5OTc2MjcxODlkM2E0YjFhN2QxNjMxZmNmODkxOTQwZGU3
10
- MGI5ZDdmMmM0YTZhYmZkMDA5MGQwMjM4YTAwNzM1ZjA4NGM5NjA3YWFmZGMy
11
- MTc3ZWNmM2M1ZDcxNTJmYjc5YmJlMTc3YTM5MDgxNGM5YjRjMzU=
9
+ MzM4NjBiMWRiMThmNGQxNmUxMDE2YTM4Njg3OTFjYmExMWRjODFkMDBhMTIy
10
+ ODQ3OWExM2I2YzkwYzFiMDQ1NThmNmMyNDYzN2Q0Y2RhZWU3ZmRhMTVlN2I5
11
+ ZmI3MjJjNTUzNzc5ZTgzM2U1ZDQwN2Q4OWIwYjgwNDUyNGNmODE=
12
12
  data.tar.gz: !binary |-
13
- YzA3Zjg5NmI5NTdiOTljYWI5ZDFjZDY4N2Q5ZDA1YTQ0ZDNmODdmOThkYWM5
14
- MWZiODgxZDZhZTBhNmFjMDRiZDgzNGFkOGQwZjBhMDNlM2Y2M2I4ZjRjY2Y2
15
- MThmYjM2N2Y2ZGZiYjEwZmI4NzhjNzZiY2E3OGJiOTU5ZDVlNjI=
13
+ MTZlZjQyMTAzMzFkYmI5ZDQyNWY0MWQ4M2M2YjE2MWRlYTk4MTA3YTIzZDc1
14
+ ZWQ1NTk4YzllMDU1Y2I4M2EzODY2NzVhMzk3YmFhMDRmMGU0NTRmNjdhZTQz
15
+ MTA4NDU3NzQwODRjYWMyNzIyMWYxMzkxYjY3OGIzNjRiYzliZTA=
data/UPGRADE.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 0.3.6
2
+
3
+
4
+
5
+
6
+
1
7
  ## 0.3.4
2
8
 
3
9
  * QUGC-154 disable
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.4
1
+ 0.3.6
File without changes
@@ -13,6 +13,8 @@ require 'quandl/command/task/threading'
13
13
  require 'quandl/command/task/translations'
14
14
  require 'quandl/command/task/updatable'
15
15
  require 'quandl/command/task/clientable'
16
+ require 'quandl/command/task/validations'
17
+ require 'quandl/command/task/dependable'
16
18
  require 'quandl/command/task/inputable'
17
19
 
18
20
  module Quandl
@@ -24,6 +26,8 @@ class Task
24
26
 
25
27
  include Quandl::Command::Task::Configurable
26
28
  include Quandl::Command::Task::Callbacks
29
+ include Quandl::Command::Task::Dependable
30
+ include Quandl::Command::Task::Validations
27
31
  include Quandl::Command::Task::Commandable
28
32
  include Quandl::Command::Task::Logging
29
33
  include Quandl::Command::Task::Presentation
@@ -9,34 +9,15 @@ module Callbacks
9
9
  included do
10
10
 
11
11
  extend ActiveModel::Callbacks
12
- define_model_callbacks :execute
13
-
14
- before_execute :run_task_validations!
12
+ define_model_callbacks :execute, :call
15
13
 
16
14
  end
17
15
 
18
- module ClassMethods
19
-
20
- def disable_in_gem!
21
- before_execute :disable_in_gem!
22
- end
23
-
24
- end
25
-
26
- def run_task_validations!
27
- unless valid?
28
- error( table(errors.full_messages) )
29
- false
30
- end
31
- end
32
-
33
- def disable_in_gem!
34
- if force_yes?
35
- info("You have forced update!")
36
- true
37
- elsif Dir.exists?( File.join( Tasks.root, ".git") ) || File.exists?( File.join( Tasks.root, "Gemfile") )
38
- fatal("#{self.class.command_name} is only permitted when installed as a package! http://quandl.com/help/toolbelt")
39
- false
16
+ def call
17
+ run_callbacks(:call) do
18
+ run_callbacks(:execute) do
19
+ execute
20
+ end
40
21
  end
41
22
  end
42
23
 
@@ -19,10 +19,6 @@ module Clientable
19
19
  before_execute :warn_unauthenticated_users
20
20
  end
21
21
 
22
- def autoload_quandl_client
23
- before_execute :autoload_quandl_client
24
- end
25
-
26
22
  end
27
23
 
28
24
  def current_user
@@ -48,16 +44,6 @@ module Clientable
48
44
  error("WARN: Authenticate your requests! 'quandl login' OR --token xyz923") if auth_token.blank?
49
45
  end
50
46
 
51
- def autoload_quandl_client
52
- require 'thread/pool'
53
- require 'quandl/format'
54
- require 'quandl/command/client_ext'
55
- Quandl::Client.use( quandl_url )
56
- Quandl::Client.token = auth_token
57
- Quandl::Client.request_source = 'quandl_command'
58
- Quandl::Client.request_version = Quandl::Command::VERSION
59
- end
60
-
61
47
  end
62
48
 
63
49
  end
@@ -78,17 +78,11 @@ module Commandable
78
78
 
79
79
  end
80
80
 
81
- def call
82
- run_callbacks(:execute) do
83
- execute
84
- end
85
- end
86
-
87
81
  def execute
88
82
  # fire a subcommand if specified
89
83
  return self.send(args.shift) if args.first.present? && self.respond_to?(args.first)
90
84
  # otherwise show syntax
91
- puts " SYNTAX\n\n #{self.class.syntax}"
85
+ info(syntax)
92
86
  end
93
87
 
94
88
  def initialize(args, options)
@@ -96,6 +90,11 @@ module Commandable
96
90
  self.options = options
97
91
  end
98
92
 
93
+ protected
94
+
95
+ def syntax
96
+ " SYNTAX\n\n #{self.class.syntax}"
97
+ end
99
98
 
100
99
  end
101
100
 
@@ -0,0 +1,70 @@
1
+ module Quandl
2
+ module Command
3
+ class Task
4
+
5
+ module Dependable
6
+
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ before_call :require_dependencies
11
+ end
12
+
13
+ module ClassMethods
14
+
15
+ def autoload_quandl_client
16
+ before_call :autoload_quandl_client
17
+ end
18
+
19
+ def disable_in_gem!
20
+ before_call :disable_in_gem!
21
+ end
22
+
23
+ def depends(*args)
24
+ args.each do |arg|
25
+ arg = arg.to_s
26
+ self.dependencies << arg unless dependencies.include?(arg)
27
+ end
28
+ end
29
+
30
+ def dependencies
31
+ @dependencies ||= []
32
+ end
33
+
34
+ end
35
+
36
+ private
37
+
38
+ def require_dependencies
39
+ self.class.dependencies.each do |d|
40
+ debug("require #{d}")
41
+ require(d)
42
+ end
43
+ true
44
+ end
45
+
46
+ def disable_in_gem!
47
+ if force_yes?
48
+ info("You have forced update!")
49
+ true
50
+ elsif Dir.exists?( File.join( Tasks.root, ".git") ) || File.exists?( File.join( Tasks.root, "Gemfile") )
51
+ fatal("#{self.class.command_name} is only permitted when installed as a package! http://quandl.com/help/toolbelt")
52
+ false
53
+ end
54
+ end
55
+
56
+ def autoload_quandl_client
57
+ require 'thread/pool'
58
+ require 'quandl/format'
59
+ require 'quandl/command/client_ext'
60
+ Quandl::Client.use( quandl_url )
61
+ Quandl::Client.token = auth_token
62
+ Quandl::Client.request_source = 'quandl_command'
63
+ Quandl::Client.request_version = Quandl::Command::VERSION
64
+ end
65
+
66
+ end
67
+
68
+ end
69
+ end
70
+ end
@@ -7,9 +7,9 @@ module Logging
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  included do
10
- before_execute :start_request_timer
10
+ before_call :start_request_timer
11
11
  before_execute :configure_logger
12
- after_execute :log_request_time
12
+ after_call :log_request_time
13
13
 
14
14
  attr_accessor :request_timer
15
15
 
@@ -33,7 +33,7 @@ module Logging
33
33
  end
34
34
 
35
35
  def log_request_time
36
- debug("# Started: #{request_timer}. Finished: #{Time.now}. Elapsed: #{request_timer.elapsed_ms}")
36
+ debug("Started: #{request_timer}. Finished: #{Time.now}. Elapsed: #{request_timer.elapsed_ms}")
37
37
  end
38
38
 
39
39
  def summarize(item)
@@ -26,7 +26,6 @@ module Presentation
26
26
  def get_output_format(override={})
27
27
  format = options.output_format || config.output_format || override[:output_format] || 'pipes'
28
28
  format = 'pipes' unless %w{ pipes json qdf }.include?(format.to_s)
29
- debug("output_format: #{format}")
30
29
  format
31
30
  end
32
31
 
@@ -18,14 +18,15 @@ module Threading
18
18
  end
19
19
 
20
20
  def shutdown_thread_pool_on_sigint
21
+ debug("starting up with #{threads} threads")
21
22
  return unless threads?
22
23
  trap('SIGINT') do
23
- debug "# exit signal received"
24
+ debug "exit signal received"
24
25
  unless thread_pool.shutdown?
25
- debug "# waiting for executing jobs to finish"
26
+ debug "waiting for executing jobs to finish"
26
27
  thread_pool.shutdown
27
28
  end
28
- debug "# exiting now"
29
+ debug "exiting now"
29
30
  exit
30
31
  end
31
32
  end
@@ -96,7 +97,7 @@ module Threading
96
97
  end
97
98
 
98
99
  def threads
99
- options.threads.to_i || 10
100
+ @threads ||= options.threads.present? ? options.threads.to_i : 10
100
101
  end
101
102
 
102
103
  def exiting?
@@ -0,0 +1,25 @@
1
+ module Quandl
2
+ module Command
3
+ class Task
4
+
5
+ module Validations
6
+
7
+ extend ActiveSupport::Concern
8
+
9
+ included do
10
+ before_execute :run_task_validations!
11
+ end
12
+
13
+ def run_task_validations!
14
+ unless valid?
15
+ debug("run_task_validations! valid? false")
16
+ error( table(errors.full_messages) )
17
+ false
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -1,6 +1,7 @@
1
1
  require 'quandl/command/tasks/search'
2
2
 
3
3
  class Quandl::Command::Tasks::List < Quandl::Command::Tasks::Search
4
+
4
5
  autoload_quandl_client
5
6
 
6
7
  description "List datasets matching conditions."
@@ -1,6 +1,7 @@
1
1
  class Quandl::Command::Tasks::Schedule < Quandl::Command::Task
2
2
 
3
- before_execute :require_dependencies
3
+ depends 'chronic', 'whedon', 'open-uri'
4
+
4
5
  autoload_quandl_client
5
6
  authenticated_users_only!
6
7
 
@@ -31,20 +32,31 @@ class Quandl::Command::Tasks::Schedule < Quandl::Command::Task
31
32
  at: "Time to run your script in UTC timezone. e.g. '14:30','7pm Monday', 'friday 13:00'"
32
33
  }
33
34
  })
34
-
35
+
35
36
  DAYS_OF_THE_WEEK = %w(Sunday Monday Tuesday Wednesday Thursday Friday Saturday)
36
-
37
+
38
+ validate :cron_at_should_be_valid!
39
+
40
+ def execute
41
+ # fire a subcommand if specified
42
+ return self.send(args.shift) if args.first.present? && self.respond_to?(args.first)
43
+ # otherwise fire add
44
+ return add if args.first.present?
45
+ # otherwise display syntax
46
+ info(syntax)
47
+ end
48
+
37
49
  def list
38
50
  if args.first
51
+ (info("'#{name}' does not exist "); return;) if scraper.blank?
39
52
  script_info scraper
40
53
  else
41
54
  scrapers.each { |x| script_info x}
42
55
  end
43
56
  end
44
-
45
57
 
46
58
  def add
47
- result=Quandl::Client::Scraper.create( name: name, scraper: args.first, schedule_at: cron_at)
59
+ result=Quandl::Client::Scraper.create( name: name, scraper: args.first, schedule_at: cron_at_utc)
48
60
  if result.valid?
49
61
  info("You have successfully scheduled '#{scraper.name}'.")
50
62
  info("#{schedule_message}")
@@ -55,7 +67,6 @@ class Quandl::Command::Tasks::Schedule < Quandl::Command::Task
55
67
 
56
68
  def download
57
69
  begin
58
- require 'open-uri'
59
70
  $stdout << open(scraper.scraper_url, {ssl_verify_mode: OpenSSL::SSL::VERIFY_NONE}).read
60
71
  rescue => err
61
72
  present err
@@ -78,15 +89,14 @@ class Quandl::Command::Tasks::Schedule < Quandl::Command::Task
78
89
 
79
90
  def replace
80
91
  (info("'#{name}' does not exist "); return;) if scraper.blank?
81
- cron_at #validate if cron format is valid before deleting scraper
82
92
  info("You are about to replace '#{scraper.name}'")
83
93
  return unless confirmed?
84
94
  scraper.scraper = args.first
85
- scraper.schedule_at = cron_at
95
+ scraper.schedule_at = cron_at_utc
86
96
  scraper.save
87
97
  if scraper.valid?
88
98
  info("You have successfully replaced '#{scraper.name}'.")
89
- info("#{schedule_message}")
99
+ info("#{schedule_message}") if cron_at
90
100
  else
91
101
  error "#{Quandl::Command::Presenter.pretty_errors(scraper.errors.messages).to_s.gsub("\n", ' ')}"
92
102
  end
@@ -94,11 +104,6 @@ class Quandl::Command::Tasks::Schedule < Quandl::Command::Task
94
104
 
95
105
  private
96
106
 
97
- def require_dependencies
98
- require 'chronic'
99
- require 'whedon'
100
- end
101
-
102
107
  def script_info(script)
103
108
  unless script.schedule_at.empty?
104
109
  info("#{(script.name+'.').ljust(20)} Scheduled: #{script_run_time(script.schedule_at)}")
@@ -119,10 +124,10 @@ class Quandl::Command::Tasks::Schedule < Quandl::Command::Task
119
124
 
120
125
  def schedule_message
121
126
  if options.at
122
- "Your script first run will happen #{script_next_run(cron_at).strftime("on %d %B at %H:%M (UTC)")}. It will continue to run #{script_run_time(cron_at)}
127
+ "Your script first run will happen #{script_next_run(cron_at).strftime("on %d %B at %H:%M")}. It will continue to run #{script_run_time(cron_at_utc)}
123
128
  Check your scrapers run status at #{quandl_url.gsub(/\/api\/?/,'')}/scrapers"
124
129
  else
125
- "It will run 3 times a day starting immediately.\n Check your scrapers run status at #{quandl_url.gsub(/\/api\/?/,'')}/scrapers"
130
+ "It will run 3 times a day starting immediately.\nCheck your scrapers run status at #{quandl_url.gsub(/\/api\/?/,'')}/scrapers"
126
131
  end
127
132
  end
128
133
 
@@ -144,8 +149,15 @@ Check your scrapers run status at #{quandl_url.gsub(/\/api\/?/,'')}/scrapers"
144
149
 
145
150
  def cron_at
146
151
  return nil unless options.at
147
- time_value=Chronic.parse(options.at)
148
- error "#{options.at} is invalid time" if time_value.nil?
152
+ time_to_cron Chronic.parse(options.at)
153
+ end
154
+
155
+ def cron_at_utc
156
+ return nil unless options.at
157
+ time_to_cron Chronic.parse(options.at).utc
158
+ end
159
+
160
+ def time_to_cron(time_value)
149
161
  day_of_the_week = options.at =~ (/Mon|Tue|Wed|Thu|Fri|Sat|Sun/i) ? time_value.wday : '*'
150
162
  "#{time_value.min} #{time_value.hour} * * #{day_of_the_week}"
151
163
  end
@@ -154,5 +166,14 @@ Check your scrapers run status at #{quandl_url.gsub(/\/api\/?/,'')}/scrapers"
154
166
  return options.remote_name if options.remote_name.present?
155
167
  return File.basename(args.first) if args.first.present?
156
168
  end
157
-
169
+
170
+ def cron_at_should_be_valid!
171
+ if options.at.present? && !Chronic.parse(options.at)
172
+ self.errors.add(:base,"#{options.at} is invalid time format" )
173
+ return false
174
+ end
175
+ true
176
+ end
177
+
178
+
158
179
  end
@@ -3,7 +3,7 @@ class Quandl::Command::Tasks::Superset < Quandl::Command::Task
3
3
  autoload_quandl_client
4
4
  authenticated_users_only!
5
5
 
6
- description "Superset a script to be run in the quandl cloud."
6
+ description "Define a superset"
7
7
  syntax %{quandl superset command [file]
8
8
 
9
9
  COMMANDS:
@@ -1,5 +1,7 @@
1
1
  class Quandl::Command::Tasks::Update < Quandl::Command::Task
2
-
2
+
3
+ depends 'uri', 'net/http', 'quandl/utility/config', 'zlib', 'archive/tar/minitar'
4
+
3
5
  # curl -s https://s3.amazonaws.com/quandl-command/install.sh | bash
4
6
 
5
7
  description "Update Quandl Toolbelt to the latest version."
@@ -31,8 +33,6 @@ class Quandl::Command::Tasks::Update < Quandl::Command::Task
31
33
  end
32
34
 
33
35
  def execute
34
- # load libraries needed by this action
35
- require_dependencies
36
36
  info "Updating from #{Quandl::Command::VERSION} ... "
37
37
  # wipe update/ and backup/ folders
38
38
  prepare_for_update
@@ -51,7 +51,7 @@ class Quandl::Command::Tasks::Update < Quandl::Command::Task
51
51
 
52
52
  rescue => err
53
53
  # log error
54
- error(err)
54
+ info(err)
55
55
  debug(err.backtrace.join("\n"))
56
56
  # report failure and rollback
57
57
  info("----\nAn error has occured! Rolling back to previous version ... ")
@@ -90,15 +90,7 @@ class Quandl::Command::Tasks::Update < Quandl::Command::Task
90
90
 
91
91
 
92
92
  private
93
-
94
- def require_dependencies
95
- require 'uri'
96
- require 'net/http'
97
- require 'quandl/utility/config'
98
- require 'zlib'
99
- require 'archive/tar/minitar'
100
- end
101
-
93
+
102
94
  def prepare_for_update
103
95
  [backup_path, update_path].each do |path|
104
96
  # remove previous directory if present
@@ -1,7 +1,7 @@
1
1
  class Quandl::Command::Tasks::Upload < Quandl::Command::Task
2
2
  autoload_quandl_client
3
3
 
4
- description "Upload a dataset using its quandl code."
4
+ description "Upload one or more datasets."
5
5
  syntax %{quandl upload file.qdf
6
6
 
7
7
  EXAMPLES:
@@ -33,6 +33,7 @@ class Quandl::Command::Tasks::Upload < Quandl::Command::Task
33
33
  interface = file_path.present? ? File.open(file_path, "r") : $stdin
34
34
  # for each dataset streamed from interface
35
35
  Quandl::Format::Dataset.each_line(interface) do |dataset, error|
36
+ debug("started processing #{dataset.full_code}") if dataset.respond_to?(:full_code)
36
37
  # present error if given
37
38
  next present( error ) unless error.nil?
38
39
  # process in background using thread key
data/quandl.gemspec CHANGED
@@ -20,10 +20,10 @@ Gem::Specification.new do |s|
20
20
  s.add_runtime_dependency "commander", '4.1.5'
21
21
 
22
22
  s.add_runtime_dependency "quandl_format", "0.4.2"
23
- s.add_runtime_dependency "quandl_client", '2.7.7'
23
+ s.add_runtime_dependency "quandl_client", '2.7.8'
24
24
  s.add_runtime_dependency "quandl_data", '1.4.1'
25
25
  s.add_runtime_dependency "quandl_operation", '0.3.2'
26
- s.add_runtime_dependency "quandl_babelfish", '0.0.9'
26
+ s.add_runtime_dependency "quandl_babelfish", '0.0.10'
27
27
  s.add_runtime_dependency "quandl_logger", '0.2.5'
28
28
  s.add_runtime_dependency "json", '1.7.7'
29
29
  s.add_runtime_dependency "minitar", '0.5.4'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quandl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Blake Hilscher
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-22 00:00:00.000000000 Z
11
+ date: 2014-04-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: commander
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - '='
46
46
  - !ruby/object:Gem::Version
47
- version: 2.7.7
47
+ version: 2.7.8
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - '='
53
53
  - !ruby/object:Gem::Version
54
- version: 2.7.7
54
+ version: 2.7.8
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: quandl_data
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -86,14 +86,14 @@ dependencies:
86
86
  requirements:
87
87
  - - '='
88
88
  - !ruby/object:Gem::Version
89
- version: 0.0.9
89
+ version: 0.0.10
90
90
  type: :runtime
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - '='
95
95
  - !ruby/object:Gem::Version
96
- version: 0.0.9
96
+ version: 0.0.10
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: quandl_logger
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -330,6 +330,7 @@ files:
330
330
  - dist/resources/ruby/PackageInfo
331
331
  - lib/commander/command/quandl_ext.rb
332
332
  - lib/quandl/command.rb
333
+ - lib/quandl/command/client.rb
333
334
  - lib/quandl/command/client_ext.rb
334
335
  - lib/quandl/command/client_ext/user.rb
335
336
  - lib/quandl/command/compatibility_check.rb
@@ -347,6 +348,7 @@ files:
347
348
  - lib/quandl/command/task/clientable.rb
348
349
  - lib/quandl/command/task/commandable.rb
349
350
  - lib/quandl/command/task/configurable.rb
351
+ - lib/quandl/command/task/dependable.rb
350
352
  - lib/quandl/command/task/inputable.rb
351
353
  - lib/quandl/command/task/logging.rb
352
354
  - lib/quandl/command/task/presentation.rb
@@ -354,6 +356,7 @@ files:
354
356
  - lib/quandl/command/task/threading.rb
355
357
  - lib/quandl/command/task/translations.rb
356
358
  - lib/quandl/command/task/updatable.rb
359
+ - lib/quandl/command/task/validations.rb
357
360
  - lib/quandl/command/tasks.rb
358
361
  - lib/quandl/command/tasks/delete.rb
359
362
  - lib/quandl/command/tasks/download.rb