mode 0.0.5 → 0.0.7

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.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/README.md +17 -22
  4. data/bin/mode +1 -1
  5. data/lib/mode.rb +34 -6
  6. data/lib/mode/api/form.rb +53 -0
  7. data/lib/mode/api/link.rb +31 -0
  8. data/lib/mode/api/request.rb +181 -0
  9. data/lib/mode/api/resource.rb +67 -0
  10. data/lib/mode/auth/access_token.rb +23 -0
  11. data/lib/mode/cli.rb +3 -3
  12. data/lib/mode/cli/analyze.rb +1 -1
  13. data/lib/mode/cli/base.rb +5 -0
  14. data/lib/mode/cli/connect.rb +18 -0
  15. data/lib/mode/cli/helpers.rb +0 -9
  16. data/lib/mode/cli/import.rb +9 -38
  17. data/lib/mode/cli/login.rb +13 -0
  18. data/lib/mode/cli/package.rb +2 -5
  19. data/lib/mode/commands/analyze_field.rb +20 -21
  20. data/lib/mode/commands/analyze_schema.rb +69 -48
  21. data/lib/mode/commands/connect.rb +78 -0
  22. data/lib/mode/commands/helpers.rb +54 -0
  23. data/lib/mode/commands/import.rb +209 -20
  24. data/lib/mode/commands/login.rb +111 -0
  25. data/lib/mode/config.rb +13 -33
  26. data/lib/mode/configurable.rb +46 -0
  27. data/lib/mode/connector/config.rb +31 -0
  28. data/lib/mode/connector/daemon.rb +27 -0
  29. data/lib/mode/connector/data_source.rb +75 -0
  30. data/lib/mode/connector/dataset.rb +13 -0
  31. data/lib/mode/connector/message.rb +31 -0
  32. data/lib/mode/connector/poller.rb +27 -0
  33. data/lib/mode/connector/processor.rb +58 -0
  34. data/lib/mode/connector/registrar.rb +36 -0
  35. data/lib/mode/connector/scheduler.rb +62 -0
  36. data/lib/mode/connector/selector.rb +47 -0
  37. data/lib/mode/connector/type_map.rb +45 -0
  38. data/lib/mode/connector/uploader.rb +50 -0
  39. data/lib/mode/logger.rb +202 -0
  40. data/lib/mode/version.rb +1 -1
  41. data/mode.gemspec +13 -2
  42. data/spec/api/form_spec.rb +51 -0
  43. data/spec/api/link_spec.rb +23 -0
  44. data/spec/api/request_spec.rb +111 -0
  45. data/spec/api/resource_spec.rb +70 -0
  46. data/spec/auth/access_token_spec.rb +22 -0
  47. data/spec/commands/analyze_field_spec.rb +26 -0
  48. data/spec/commands/analyze_schema_spec.rb +7 -5
  49. data/spec/commands/connect_spec.rb +80 -0
  50. data/spec/commands/helpers_spec.rb +69 -0
  51. data/spec/commands/import_spec.rb +155 -0
  52. data/spec/commands/login_spec.rb +178 -0
  53. data/spec/config_spec.rb +9 -7
  54. data/spec/connector/config_spec.rb +46 -0
  55. data/spec/connector/daemon_spec.rb +30 -0
  56. data/spec/connector/data_source_spec.rb +73 -0
  57. data/spec/connector/message_spec.rb +22 -0
  58. data/spec/connector/poller_spec.rb +26 -0
  59. data/spec/connector/processor_spec.rb +93 -0
  60. data/spec/connector/registrar_spec.rb +53 -0
  61. data/spec/connector/scheduler_spec.rb +93 -0
  62. data/spec/connector/selector_spec.rb +54 -0
  63. data/spec/connector/type_map_spec.rb +45 -0
  64. data/spec/connector/uploader_spec.rb +55 -0
  65. data/spec/fixtures/country-codes/README.md +71 -0
  66. data/spec/fixtures/country-codes/data/country-codes.csv +250 -0
  67. data/spec/fixtures/country-codes/datapackage.json +142 -0
  68. data/spec/fixtures/country-codes/scripts/get_countries_of_earth.py +370 -0
  69. data/spec/fixtures/country-codes/scripts/reorder_columns.py +8 -0
  70. data/spec/fixtures/country-codes/scripts/requirements.pip +2 -0
  71. data/spec/fixtures/espn_draft.csv +473 -1
  72. data/spec/fixtures/espn_draft/data.csv +473 -0
  73. data/spec/fixtures/espn_draft/datapackage.json +43 -0
  74. data/spec/logger_spec.rb +79 -0
  75. data/spec/spec_helper.rb +6 -1
  76. metadata +156 -19
  77. data/lib/mode/cli/setup.rb +0 -12
  78. data/lib/mode/commands/package.rb +0 -56
  79. data/lib/mode/commands/setup.rb +0 -36
  80. data/lib/mode/package_builder.rb +0 -57
  81. data/spec/commands/setup_spec.rb +0 -62
  82. data/spec/fixtures/MOCK_DATA.csv +0 -100001
  83. data/spec/fixtures/cb_clean_small.csv +0 -100000
  84. data/spec/fixtures/duplicate_keys.csv +0 -3
  85. data/spec/fixtures/format_examples.csv.txt +0 -6
  86. data/spec/fixtures/format_examples_after_excel.csv.txt +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6bfab7e5e64907e822459c3d0750038e99ea0ce7
4
- data.tar.gz: 6dfeb3b3138921cf3b95439d3b5d7775cee76025
3
+ metadata.gz: 916fc74b44c1c5b65091492b449464196a27067c
4
+ data.tar.gz: 41bdef70c556a8b1807e5e9f8fb71bfce3a39ded
5
5
  SHA512:
6
- metadata.gz: e69bfae6c5ba1335c3755c376871e2406a1e1615427d5578913fd41799c9808d606034727691bf87f71b6affe0c82a137f6e665e52e32c640256c12e4c6b7c18
7
- data.tar.gz: 38a4242c9208533c02730ce09382810104b00769c9eec976f137de5a1accb5e7f2f53d55a1f692c154b9ad52be591efa81c027b6638bc0f2cd2302081023cbb7
6
+ metadata.gz: aba504acfea6ea6cd6052666abd9f826c44e1241ba738b523089bedd8e4e700f4d40e78ba1c5df9adf8d6dfcf0f03003564114cf29a79bc597d98fca31ecbf4e
7
+ data.tar.gz: 0fc687a9b19413e7c47339aaa6ddd215145a374f1cbb5d068b37c2c5b134891553c3ff69d1a8891c805f3c97f4594bedac2778374986e632b487db28d3666858
data/.gitignore CHANGED
@@ -15,4 +15,5 @@ rdoc
15
15
  spec/reports
16
16
  test/tmp
17
17
  test/version_tmp
18
- tmp
18
+ tmp
19
+ data_packages/*
data/README.md CHANGED
@@ -6,7 +6,18 @@ This package provides command line tools for managing datasets and connecting da
6
6
  * Personal data warehouse connectivity
7
7
  * Dataset formatting and importing (CSV)
8
8
 
9
- ## Prerequisites
9
+
10
+ ## Install Mode
11
+
12
+ **Mode requires Ruby 1.9 or newer**
13
+
14
+ If you don't currently have Ruby 1.9 or aren't sure then follow the directions for installing it before continuing.
15
+
16
+ ```
17
+ gem install mode
18
+ ```
19
+
20
+ ## Install Ruby 1.9+ if it's not currently installed.
10
21
 
11
22
  This package requires at least Ruby 1.9 and Ruby 2.0 is recommended.
12
23
 
@@ -26,26 +37,18 @@ ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
26
37
 
27
38
  ```
28
39
  brew update
29
- brew install rbenv ruby-build
40
+ brew install rbenv ruby-build rbenv-gem-rehash
30
41
  echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
31
42
  source ~/.bash_profile
32
43
  ```
33
44
 
34
- 3\. Install Ruby 2.0
45
+ 3\. Install Ruby
35
46
 
36
47
  Note: This usually takes several minutes
37
48
 
38
49
  ```
39
50
  rbenv install 2.0.0-p353
40
51
  rbenv global 2.0.0-p353
41
- rbenv rehash
42
- ```
43
-
44
- 4\. Install the mode gem
45
-
46
- ```
47
- gem install mode
48
- rbenv rehash
49
52
  ```
50
53
 
51
54
  ### OSX Combined
@@ -55,29 +58,21 @@ For convenience you can just copy and paste all the lines at once into your term
55
58
  ```
56
59
  ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/go/install)"
57
60
  brew update
58
- brew install rbenv ruby-build
61
+ brew install rbenv ruby-build rbenv-gem-rehash
59
62
  echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
60
63
  source ~/.bash_profile
61
64
  rbenv install 2.0.0-p353
62
65
  rbenv global 2.0.0-p353
63
- gem install mode
64
- rbenv rehash
65
66
  ```
66
67
 
67
68
  ### Windows
68
69
 
69
70
  To install a current version of Ruby on windows complete the 2 steps below.
70
71
 
71
- 1\. Install Ruby 2.0
72
+ 1\. Install Ruby
72
73
 
73
74
  You can download the latest ruby version from [RubyInstaller](http://rubyinstaller.org/downloads/).
74
75
 
75
- 2\. Install the mode gem
76
-
77
- ```
78
- $ gem install mode
79
- ```
80
-
81
76
  ## Setup
82
77
 
83
78
  ### Init
@@ -85,7 +80,7 @@ $ gem install mode
85
80
  Initializes a new configuration file at the specified path which holds API credentials and other information
86
81
 
87
82
  ```
88
- $ mode setup
83
+ $ mode login
89
84
 
90
85
  Initializing configuration at /Users/josh/.mode.yml
91
86
  Mode username: besquared
data/bin/mode CHANGED
@@ -10,4 +10,4 @@ rescue LoadError
10
10
  require 'mode/cli'
11
11
  end
12
12
 
13
- Mode::CLI::Base.start(ARGV)
13
+ Mode::CLI::Base.start(ARGV)
@@ -1,19 +1,47 @@
1
1
  require 'thor'
2
+ require 'faraday'
2
3
  require 'data_kit'
3
4
  require 'data_package'
4
5
 
5
6
  require 'mode/version'
6
7
 
7
- # Config
8
+ # Config & Logging
9
+ require 'mode/configurable'
8
10
  require 'mode/config'
11
+ require 'mode/logger'
12
+
13
+ # Auth
14
+ require 'mode/auth/access_token'
15
+
16
+
17
+ # API
18
+ require 'mode/api/link'
19
+ require 'mode/api/form'
20
+ require 'mode/api/resource'
21
+ require 'mode/api/request'
22
+
23
+ # Connector
24
+ require 'mode/connector/config'
25
+ require 'mode/connector/type_map'
26
+ require 'mode/connector/data_source'
27
+ require 'mode/connector/dataset'
28
+
29
+ require 'mode/connector/registrar'
30
+ require 'mode/connector/scheduler'
31
+ require 'mode/connector/poller'
32
+ require 'mode/connector/processor'
33
+ require 'mode/connector/selector'
34
+ require 'mode/connector/uploader'
35
+
36
+ require 'mode/connector/daemon'
37
+ require 'mode/connector/message'
38
+
9
39
 
10
40
  # Commands
11
41
  require 'mode/commands/helpers'
12
- require 'mode/commands/setup'
42
+
43
+ require 'mode/commands/login'
13
44
  require 'mode/commands/import'
14
- require 'mode/commands/package'
45
+ require 'mode/commands/connect'
15
46
  require 'mode/commands/analyze_field'
16
47
  require 'mode/commands/analyze_schema'
17
-
18
- # Utilities
19
- require 'mode/package_builder'
@@ -0,0 +1,53 @@
1
+ module Mode
2
+ module API
3
+ class Form
4
+ attr_reader :content
5
+
6
+ def initialize(content)
7
+ @content = content
8
+ end
9
+
10
+ def method
11
+ content['method']
12
+ end
13
+
14
+ def action
15
+ content['action']
16
+ end
17
+
18
+ def input(name)
19
+ content['input'][name]
20
+ end
21
+
22
+ def submit!(params = {})
23
+ inputs = content['input']
24
+ params = input_values(inputs, params)
25
+ Mode::API::Request.send(method.to_sym, action, params)
26
+ end
27
+
28
+ private
29
+
30
+ def input_values(inputs, params = {})
31
+ merged = {}
32
+ return merged if inputs.nil?
33
+
34
+ inputs.each do |name, value|
35
+ if value.instance_of?(Hash)
36
+ if value.has_key?('value')
37
+ # we reached a leaf
38
+ merged[name] = params[name] || value['value']
39
+ else
40
+ # we're at an intermediate node
41
+ merged[name] = input_values(value, params[name])
42
+ end
43
+ else
44
+ # non-field node
45
+ # merged[name] = params[name]
46
+ end
47
+ end
48
+
49
+ merged
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,31 @@
1
+ require 'uri_template'
2
+
3
+ module Mode
4
+ module API
5
+ class Link
6
+ attr_reader :content
7
+
8
+ def initialize(content)
9
+ @content = content
10
+ end
11
+
12
+ def href
13
+ content['href']
14
+ end
15
+
16
+ def templated
17
+ content['templated']
18
+ end
19
+
20
+ def expand(params = {})
21
+ template.expand(params)
22
+ end
23
+
24
+ private
25
+
26
+ def template
27
+ URITemplate.new(href)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,181 @@
1
+ require 'uri'
2
+ require 'json'
3
+ require 'faraday'
4
+
5
+ module Mode
6
+ module API
7
+ class Request
8
+ attr_reader :method, :path, :params
9
+
10
+ def initialize(method, path, params = {})
11
+ @method = method
12
+ @path = path
13
+ @params = params
14
+ end
15
+
16
+ def perform
17
+ response = http.send(method.to_sym, path, params)
18
+ response.success? ? success(response) : error(response)
19
+ end
20
+
21
+ private
22
+
23
+ def http
24
+ @http ||= self.class.http
25
+ end
26
+
27
+ def parsed_body(response)
28
+ JSON.parse(response.body)
29
+ end
30
+
31
+ def error(response)
32
+ response.tap do |response|
33
+ log_error(response)
34
+ end
35
+ end
36
+
37
+ def success(response)
38
+ log_success(response)
39
+ Mode::API::Resource.new(parsed_body(response))
40
+ end
41
+
42
+ def log_error(response)
43
+ log_response(:error, response)
44
+ end
45
+
46
+ def log_success(response)
47
+ log_response(:info, response)
48
+ end
49
+
50
+ def log_response(level, response)
51
+ Mode::Logger.instance.send(level,
52
+ "API::Request", "#{response.status}", ["#{method.upcase} #{path}"])
53
+ end
54
+
55
+ class << self
56
+ #
57
+ # Configuration
58
+ #
59
+
60
+ attr_reader :environment
61
+ attr_reader :credentials
62
+
63
+ def valid?
64
+ !environment.nil?
65
+ end
66
+
67
+ def validate!
68
+ unless valid?
69
+ raise "Request API not configured. Please provide an API environment."
70
+ end
71
+ end
72
+
73
+ def username
74
+ validate!
75
+ @credentials[:username]
76
+ end
77
+
78
+ def access_token
79
+ validate!
80
+ @credentials[:access_token]
81
+ end
82
+
83
+ def configure(environment, options = {})
84
+ @environment = environment
85
+ @credentials = options[:credentials]
86
+ end
87
+
88
+ #
89
+ # Request Methods
90
+ #
91
+
92
+ def head(path)
93
+ new(:head, resolve_path(path)).perform
94
+ end
95
+
96
+ def get(path)
97
+ new(:get, resolve_path(path)).perform
98
+ end
99
+
100
+ def post(path, params = {})
101
+ new(:post, resolve_path(path), params).perform
102
+ end
103
+
104
+ def put(path, params = {})
105
+ new(:put, resolve_path(path), params).perform
106
+ end
107
+
108
+ def delete(path, params = {})
109
+ new(:delete, resolve_path(path), params).perform
110
+ end
111
+
112
+ def resolve_path(path)
113
+ path.is_a?(Symbol) ? send("#{path}_path".to_sym) : path
114
+ end
115
+
116
+ #
117
+ # Routes
118
+ #
119
+
120
+ def base_path
121
+ "/api/#{username}"
122
+ end
123
+
124
+ def access_tokens_path
125
+ "#{base_path}/access_tokens"
126
+ end
127
+
128
+ def packages_path
129
+ "#{base_path}/packages"
130
+ end
131
+
132
+ def data_source_connections_path
133
+ "#{base_path}/data_source_connections"
134
+ end
135
+
136
+ def data_source_connection_path
137
+ [data_source_connections_path, access_token].join('/').strip
138
+ end
139
+
140
+ def data_source_connection_messages_path
141
+ [data_source_connection_path, 'messages'].join('/').strip
142
+ end
143
+
144
+ #
145
+ # Connection
146
+ #
147
+ def http(options = {})
148
+ @_http ||= Faraday.new(:url => base_url) do |builder|
149
+ builder.request :multipart # adds small overhead to each request
150
+ builder.request :url_encoded
151
+ builder.adapter Faraday.default_adapter
152
+ builder.basic_auth(username, access_token)
153
+ end
154
+ end
155
+
156
+ private
157
+
158
+ def base_url
159
+ @base_url ||= URI::HTTP.build(:host => env_host, :port => env_port)
160
+ end
161
+
162
+ def env_host
163
+ case environment.to_sym
164
+ when :test
165
+ "test"
166
+ when :development
167
+ "localhost"
168
+ when :staging
169
+ "staging.modeanalytics.com"
170
+ else
171
+ "www.modeanalytics.com"
172
+ end
173
+ end
174
+
175
+ def env_port
176
+ environment.to_sym == :development ? 3000 : 80
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
@@ -0,0 +1,67 @@
1
+ module Mode
2
+ module API
3
+ class Resource
4
+ attr_reader :content
5
+
6
+ def initialize(content)
7
+ @content = content
8
+ end
9
+
10
+ def links(name)
11
+ if has_link?(name)
12
+ Mode::API::Link.new(content['_links'][name])
13
+ else
14
+ nil
15
+ end
16
+ end
17
+
18
+ def has_link?(name)
19
+ links = content && content['_links']
20
+ links.is_a?(Hash) && links.has_key?(name)
21
+ end
22
+
23
+ def forms(name)
24
+ if has_form?(name)
25
+ Mode::API::Form.new(content['_forms'][name])
26
+ else
27
+ nil
28
+ end
29
+ end
30
+
31
+ def has_form?(name)
32
+ forms = content && content['_forms']
33
+ forms.is_a?(Hash) && forms.has_key?(name)
34
+ end
35
+
36
+ def embedded(name)
37
+ return nil unless has_embedded?(name)
38
+
39
+ embed = content['_embedded'][name]
40
+
41
+ if embed.is_a?(Array)
42
+ embed.map do |entry|
43
+ Mode::API::Resource.new(entry)
44
+ end
45
+ elsif embed.is_a?(Hash)
46
+ Mode::API::Resource.new(embed)
47
+ end
48
+ end
49
+
50
+ def has_embedded?(name)
51
+ embed = content['_embedded']
52
+ return false if embed.nil?
53
+ return false unless embed.is_a?(Hash)
54
+ return false unless embed.has_key?(name)
55
+ true
56
+ end
57
+
58
+ def method_missing(sym, *args, &block)
59
+ if content.has_key?(sym.to_s)
60
+ content[sym.to_s]
61
+ else
62
+ super
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end