datapimp 0.0.1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +2 -0
- data/Gemfile +6 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +4 -18
- data/README.md +199 -17
- data/Rakefile +24 -0
- data/bin/datapimp +18 -0
- data/datapimp.gemspec +27 -7
- data/lib/datapimp/cli/01_extensions.rb +25 -0
- data/lib/datapimp/cli/config.rb +24 -0
- data/lib/datapimp/cli/setup.rb +35 -0
- data/lib/datapimp/cli/sync.rb +29 -0
- data/lib/datapimp/cli.rb +49 -0
- data/lib/datapimp/clients/amazon.rb +172 -0
- data/lib/datapimp/clients/dropbox.rb +178 -0
- data/lib/datapimp/clients/github.rb +59 -0
- data/lib/datapimp/clients/google.rb +145 -0
- data/lib/datapimp/configuration.rb +210 -0
- data/lib/datapimp/core_ext.rb +5 -0
- data/lib/datapimp/data_sources/dropbox.rb +8 -0
- data/lib/datapimp/data_sources/excel.rb +5 -0
- data/lib/datapimp/data_sources/github.rb +5 -0
- data/lib/datapimp/data_sources/google.rb +5 -0
- data/lib/datapimp/data_sources/json.rb +5 -0
- data/lib/datapimp/data_sources/nokogiri.rb +5 -0
- data/lib/datapimp/data_sources.rb +10 -0
- data/lib/datapimp/sync/dropbox_delta.rb +67 -0
- data/lib/datapimp/sync/dropbox_folder.rb +10 -0
- data/lib/datapimp/sync/google_drive_folder.rb +5 -0
- data/lib/datapimp/sync.rb +30 -0
- data/lib/datapimp/version.rb +1 -1
- data/lib/datapimp.rb +30 -2
- data/packaging/wrapper.sh +32 -0
- data/spec/spec_helper.rb +29 -0
- data/spec/support/test_helpers.rb +7 -0
- data/tasks/distribution/configuration.rb +15 -0
- data/tasks/distribution/executable.rb +28 -0
- data/tasks/distribution/package.rb +85 -0
- data/tasks/distribution/package_helpers.rb +12 -0
- data/tasks/distribution/release.rb +49 -0
- data/tasks/distribution/release_notes.erb +14 -0
- data/tasks/distribution/release_notes.rb +62 -0
- data/tasks/distribution/tarball.rb +47 -0
- data/tasks/distribution/travelling_ruby.rb +87 -0
- data/tasks/package.rake +41 -0
- data/tasks/upload.rake +40 -0
- metadata +300 -26
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 25225d44e31870eb3e377a8fa095cc4453e49648
|
4
|
+
data.tar.gz: 2d1998a952fd6d5da7f16c67bc5ceb8441637547
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 50f0280170efb19fa6adaaf3b625e35ffb86cba675a5be09e8deee7c8f594ed988bd7649e142cb5c316905bf01d5afaa6f6de25d3e8450d758cead505bd48c47
|
7
|
+
data.tar.gz: e0f1f525c2b4a91902aef779128b67069be36d182685f0a2186446e471db9569370128a0003dc65c12a4e9f0cd7a8516b82c97286c09968594a9ac60e1fd1a95
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
data/Guardfile
ADDED
data/LICENSE.txt
CHANGED
@@ -1,22 +1,8 @@
|
|
1
1
|
Copyright (c) 2013 Jonathan Soeder
|
2
2
|
|
3
|
-
|
3
|
+
Permission to use this gem is granted on a project by project basis.
|
4
4
|
|
5
|
-
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
5
|
+
For open source projects, the license is identical to the MIT license.
|
12
6
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
-
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
7
|
+
For commercial ventures, the license is subject to the completion of a
|
8
|
+
contractual agreement between the company and Jonathan Soeder.
|
data/README.md
CHANGED
@@ -1,29 +1,211 @@
|
|
1
|
-
|
1
|
+
### Data driven API programming
|
2
2
|
|
3
|
-
|
3
|
+
This gem promotes a declarative style of developing JSON APIs that automates a lot of common patterns
|
4
|
+
found in the development of systems which have multiple users, with multiple roles and permissions.
|
4
5
|
|
5
|
-
|
6
|
+
An API is a collection of resources, and resources can be queried, or commands can be run against resources, each by certain users in certain ways depending on the user's authorization level.
|
6
7
|
|
7
|
-
|
8
|
+
The DSL provided by this gem allows you to accomplish the tasks of writing your API documentation, your integration tests, as well as your actual implementation code at the same time, and in such a way that exposes metadata.
|
8
9
|
|
9
|
-
|
10
|
+
Because the API exposes metadata about the resources it contains, their schemas, and the various policies and details about them, it is possible for API client libraries to configure themselves accordingly.
|
10
11
|
|
11
|
-
|
12
|
+
### Example
|
12
13
|
|
13
|
-
|
14
|
+
```ruby
|
15
|
+
require 'datapimp/dsl'
|
14
16
|
|
15
|
-
|
17
|
+
api :my_app => "My Application" do
|
18
|
+
version :v1
|
16
19
|
|
17
|
-
|
20
|
+
desc "Public users include anyone with access to the URL"
|
21
|
+
policy :public_users do
|
22
|
+
allow :books, :commands => false, :queries => true
|
23
|
+
end
|
18
24
|
|
19
|
-
|
25
|
+
desc "Authenticated users register and are given an auth token"
|
26
|
+
policy :logged_in_users do
|
27
|
+
authenticate_with :header => 'X-AUTH-TOKEN', :param => :auth_token
|
28
|
+
allow :books, :commands => true, :queries => true
|
29
|
+
end
|
20
30
|
|
21
|
-
|
31
|
+
desc "Admin users have the admin flag set to true"
|
32
|
+
policy :admin_users do
|
33
|
+
extends :logged_in_users
|
34
|
+
test :admin?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
```
|
22
38
|
|
23
|
-
|
39
|
+
An API can be inspected:
|
24
40
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
41
|
+
```ruby
|
42
|
+
api("My Application").authentication_header #=> "X-AUTH-TOKEN"
|
43
|
+
api("My Application").policies #=> [:public_users, :logged_in_users, :admin_users]
|
44
|
+
api("My Application").policy(:admin_users).resource(:books).allowed_commands #=> [:create, :update, :delete]
|
45
|
+
```
|
46
|
+
|
47
|
+
An API is made up of resources:
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
resource "Books" do
|
51
|
+
serializer do
|
52
|
+
desc "A unique id for the book", :type => :integer
|
53
|
+
attribute :id
|
54
|
+
|
55
|
+
desc "The title of the book", :type => :string
|
56
|
+
attribute :title
|
57
|
+
|
58
|
+
desc "The year the book was published", :type => :integer
|
59
|
+
attribute :year
|
60
|
+
|
61
|
+
desc "A reference to the author", :type => "Author"
|
62
|
+
has_one :author
|
63
|
+
end
|
64
|
+
|
65
|
+
command :update, "Update a book's attributes" do
|
66
|
+
# Will ensure the command is run with
|
67
|
+
# Book.accessible_to(current_user).find(id).
|
68
|
+
scope :accessible_to
|
69
|
+
|
70
|
+
params do
|
71
|
+
duck :id, :method => :to_s
|
72
|
+
|
73
|
+
optional do
|
74
|
+
string :title
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
query do
|
80
|
+
start_from :scope => :accessible_to
|
81
|
+
|
82
|
+
params do
|
83
|
+
desc "The year the book was published (example: YYYY)"
|
84
|
+
integer :year_published
|
85
|
+
end
|
86
|
+
|
87
|
+
role :admin do
|
88
|
+
start_from :scope => :all
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
```
|
93
|
+
|
94
|
+
A resource can also be inspected:
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
meta_data = api("My Application").resource("Books").meta_data
|
98
|
+
|
99
|
+
meta_data.attributes # {:id => "The id of the book", :year_published => "The year it was published"}
|
100
|
+
meta_data.commands => [:update]
|
101
|
+
meta_data.command(:update).arguments #=> [:id, :year, :title]
|
102
|
+
meta_data.command(:update).optional_arguments #=> [:year, :title]
|
103
|
+
```
|
104
|
+
|
105
|
+
This inspection goes a long way to some advanced features, such as
|
106
|
+
automated documentation and integration test generation, or in writing
|
107
|
+
tools for generating client libraries and the like.
|
108
|
+
|
109
|
+
### Customizing the elements
|
110
|
+
|
111
|
+
How are each of these behaviors is stored in code? In a way that will be
|
112
|
+
very familiar to Rails developers, following common naming conventions
|
113
|
+
and file organization patterns.
|
114
|
+
|
115
|
+
```
|
116
|
+
- app
|
117
|
+
- commands
|
118
|
+
- application_command.rb
|
119
|
+
- create_book.rb
|
120
|
+
- update_book.rb
|
121
|
+
- contexts
|
122
|
+
- application_context.rb
|
123
|
+
- book_context.rb
|
124
|
+
- serializers
|
125
|
+
- book_serializer.rb
|
126
|
+
```
|
127
|
+
|
128
|
+
### Request Context: Current User, Resource, and REST
|
129
|
+
|
130
|
+
From the programmer's perspective, a typical resource is made up of several request patterns:
|
131
|
+
|
132
|
+
- Filter Context (index, show)
|
133
|
+
- Commands (aka mutations. create, update, destroy)
|
134
|
+
- Serializers (aka presenters, views)
|
135
|
+
|
136
|
+
Each of these objects can be configured to behave in certain ways that may be dependent on the user or role making the request to interact with them.
|
137
|
+
|
138
|
+
Most API requests can be thought of in the following ways:
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
# A Typical read request ( query / filter or detail view )
|
142
|
+
|
143
|
+
response = present( this_resource ) # resource -> filter context
|
144
|
+
.to(this_user) # filter context: relevant for this user
|
145
|
+
.in(this_presentation) # serializer: different slices / renderings
|
146
|
+
|
147
|
+
response.cache_key # russian doll style / max-updated-at friendly
|
148
|
+
response.etag # http client conditional get
|
149
|
+
```
|
150
|
+
|
151
|
+
The filter context and serializer classes make this easy. They also
|
152
|
+
make writing -- or rather, generating -- documentation and tests very
|
153
|
+
easy as well.
|
154
|
+
|
155
|
+
```ruby
|
156
|
+
# Typical mutation request ( create, update, delete )
|
157
|
+
|
158
|
+
outcome = run(this_command)
|
159
|
+
.as(this_user)
|
160
|
+
.against(this_set_of_one_or_more_records)
|
161
|
+
.with(these_arguments)
|
162
|
+
|
163
|
+
outcome.success?
|
164
|
+
|
165
|
+
outcome.error_messages
|
166
|
+
|
167
|
+
outcome.result
|
168
|
+
```
|
169
|
+
|
170
|
+
The command class determines the specifics of the above style of
|
171
|
+
request.
|
172
|
+
|
173
|
+
### The Filter Context
|
174
|
+
|
175
|
+
The filter context system is used to standardize the way we write
|
176
|
+
typical index and show actions in a typical Rails app. A user is
|
177
|
+
requesting to view a set of records, or an individual records.
|
178
|
+
|
179
|
+
Given a user making a request to view a specific resource, we arrive at
|
180
|
+
the 'filter context'. The filter context is responsible for 'scoping' a
|
181
|
+
resource to the set of records that user is permitted to view.
|
182
|
+
|
183
|
+
Based on the combination of parameters used to build that filter, we
|
184
|
+
compute a cache key that simplifies the process of server caching and
|
185
|
+
http client caching at the same time.
|
186
|
+
|
187
|
+
The filter context itself and the available parameters and their allowed
|
188
|
+
values are specified by the DSL, which simplifies the process of writing
|
189
|
+
complex queries and also provides configuration meta-data that aids in
|
190
|
+
the process of developing client user interfaces, API documentation, and
|
191
|
+
test code.
|
192
|
+
|
193
|
+
### Commands
|
194
|
+
|
195
|
+
The command class allows you to declare the available parameters, the
|
196
|
+
required values, their data types, etc. It also allows you to declare
|
197
|
+
which users can run the command, and further restrict the parameters
|
198
|
+
allowed and the values they accept.
|
199
|
+
|
200
|
+
### Serializers
|
201
|
+
|
202
|
+
- ActiveModel Serializers
|
203
|
+
- Documentation DSL
|
204
|
+
- Metadata for inspection + documentation generation
|
205
|
+
|
206
|
+
## API Documentation & Integration Tests
|
207
|
+
|
208
|
+
- rspec_api_documentation gem
|
209
|
+
- plan: take advantage of metadata defined above to auto-generate
|
210
|
+
documentation with the ability to pass expectation blocks as pass /
|
211
|
+
fail indicators
|
data/Rakefile
CHANGED
@@ -1 +1,25 @@
|
|
1
|
+
Dir[File.join(Dir.pwd, 'tasks', '**', '*.rb')].each { |f| require f }
|
2
|
+
Dir[File.join(Dir.pwd, 'tasks', '*.rake')].each { |f| load f }
|
3
|
+
|
1
4
|
require "bundler/gem_tasks"
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
|
9
|
+
Distribution.configure do |config|
|
10
|
+
config.package_name = 'datapimp'
|
11
|
+
config.version = Datapimp::VERSION
|
12
|
+
config.rb_version = '20150210-2.1.5'
|
13
|
+
config.packaging_dir = File.expand_path 'packaging'
|
14
|
+
config.native_extensions = [
|
15
|
+
#'github-markdown-0.6.8',
|
16
|
+
#'escape_utils-1.0.1',
|
17
|
+
#'charlock_holmes-0.7.3',
|
18
|
+
#'posix-spawn-0.3.9',
|
19
|
+
#'nokogumbo-1.3.0',
|
20
|
+
#'rugged-0.21.4',
|
21
|
+
#'nokogiri-1.6.5',
|
22
|
+
]
|
23
|
+
end
|
24
|
+
|
25
|
+
task :default => :spec
|
data/bin/datapimp
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "rubygems"
|
4
|
+
require "pathname"
|
5
|
+
|
6
|
+
$:.unshift Pathname(File.dirname(__FILE__)).join("..","lib")
|
7
|
+
|
8
|
+
require "pry"
|
9
|
+
require 'colored'
|
10
|
+
require "commander/import"
|
11
|
+
require 'datapimp'
|
12
|
+
require 'datapimp/cli'
|
13
|
+
|
14
|
+
program :name, 'Datapimp'
|
15
|
+
program :version, Datapimp::VERSION
|
16
|
+
program :description, 'Datapimp style command line utilities'
|
17
|
+
|
18
|
+
Datapimp::Cli.load_commands
|
data/datapimp.gemspec
CHANGED
@@ -8,16 +8,36 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = Datapimp::VERSION
|
9
9
|
spec.authors = ["Jonathan Soeder"]
|
10
10
|
spec.email = ["jonathan.soeder@gmail.com"]
|
11
|
-
spec.description = %q{
|
12
|
-
spec.summary = %q{
|
11
|
+
spec.description = %q{Your rails app in a custom tailored suit.}
|
12
|
+
spec.summary = %q{A collection of API development patterns that I have accumulated in my career as a boss.}
|
13
13
|
spec.homepage = ""
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
|
-
spec.files = `git ls-files`.split(
|
17
|
-
spec.
|
18
|
-
spec.
|
16
|
+
spec.files = `git ls-files`.split("\n")
|
17
|
+
spec.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
|
20
|
+
spec.add_dependency 'pry'
|
21
|
+
spec.add_dependency 'hashie', '>= 0.3.0'
|
22
|
+
spec.add_dependency 'colored'
|
23
|
+
spec.add_dependency 'commander'
|
24
|
+
spec.add_dependency 'fog-aws'
|
25
|
+
spec.add_dependency 'dropbox-api'
|
26
|
+
spec.add_dependency 'google_drive'
|
27
|
+
spec.add_dependency 'rack-contrib'
|
28
|
+
spec.add_dependency 'uri_template'
|
29
|
+
spec.add_dependency 'dnsimple-ruby'
|
30
|
+
spec.add_dependency 'rack-proxy'
|
31
|
+
spec.add_dependency 'axlsx'
|
32
|
+
spec.add_dependency 'launchy'
|
33
|
+
spec.add_dependency 'oauth', '~> 0.4.7'
|
34
|
+
spec.add_dependency 'octokit', '>= 3.0.0'
|
35
|
+
|
36
|
+
spec.add_development_dependency "rake", '~> 0'
|
37
|
+
spec.add_development_dependency "rack-test", '~> 0'
|
38
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
39
|
+
spec.add_development_dependency "pry-nav", '~> 0'
|
40
|
+
|
19
41
|
spec.require_paths = ["lib"]
|
20
42
|
|
21
|
-
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
-
spec.add_development_dependency "rake"
|
23
43
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class Commander::Command
|
2
|
+
def action(*args, &block)
|
3
|
+
|
4
|
+
wrapper = lambda do |a, options|
|
5
|
+
if options.config
|
6
|
+
read = Pathname(options.config).read
|
7
|
+
json = JSON.parse(read)
|
8
|
+
|
9
|
+
Datapimp.config.apply_all(json)
|
10
|
+
end
|
11
|
+
|
12
|
+
Datapimp.config.apply_all(options.to_hash)
|
13
|
+
|
14
|
+
block.call(a, options)
|
15
|
+
end
|
16
|
+
|
17
|
+
send(:when_called, *args, &wrapper)
|
18
|
+
end
|
19
|
+
|
20
|
+
class Options
|
21
|
+
def to_hash
|
22
|
+
__hash__
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
command 'config set' do |c|
|
2
|
+
c.syntax = 'datapimp config set KEY=VALUE KEY=VALUE [options]'
|
3
|
+
c.description = 'manipulate configuration settings'
|
4
|
+
|
5
|
+
c.option '--global', 'Set the configuration globally'
|
6
|
+
c.option '--local', 'Set the configuration globally'
|
7
|
+
|
8
|
+
c.example "set a bunch of config parameters", "datapimp config set DROPBOX_APP_KEY=xxx DROPBOX_APP_SECRET=yyy GITHUB_APP_SECRET=zzz"
|
9
|
+
|
10
|
+
c.action do |args, _options|
|
11
|
+
Datapimp::Configuration.initialize!
|
12
|
+
|
13
|
+
args.select { |pair| pair.match(/=/) }
|
14
|
+
.map { |pair| pair.split('=') }
|
15
|
+
.each do |group|
|
16
|
+
key, value = group
|
17
|
+
Datapimp.config.set(key, value, false, global: !!(_options.global))
|
18
|
+
end
|
19
|
+
|
20
|
+
Datapimp.config.save!
|
21
|
+
|
22
|
+
Datapimp.config.show
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
command "setup google" do |c|
|
2
|
+
c.syntax = "datapimp set up google"
|
3
|
+
c.description = "setup integration with google drive"
|
4
|
+
|
5
|
+
c.action do |args, options|
|
6
|
+
Datapimp::Sync.google.setup()
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
command "setup amazon" do |c|
|
11
|
+
c.syntax = "datapimp setup amazon"
|
12
|
+
c.description = "setup integration with amazon"
|
13
|
+
|
14
|
+
c.action do |args, options|
|
15
|
+
Datapimp::Sync.amazon.interactive_setup()
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
command "setup dropbox" do |c|
|
20
|
+
c.syntax = "datapimp set up dropbox"
|
21
|
+
c.description = "setup integration with dropbox"
|
22
|
+
|
23
|
+
c.action do |args, options|
|
24
|
+
Datapimp::Sync.dropbox.setup()
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
command "setup github" do |c|
|
29
|
+
c.syntax = "datapimp set up github"
|
30
|
+
c.description = "setup integration with github"
|
31
|
+
|
32
|
+
c.action do |args, options|
|
33
|
+
Datapimp::Sync.github.setup()
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
command "sync folder" do |c|
|
2
|
+
c.description = "Synchronize the contents of a local folder with a file sharing service"
|
3
|
+
c.syntax = "datapimp sync folder LOCAL_PATH REMOTE_PATH [OPTIONS]"
|
4
|
+
|
5
|
+
c.option '--type TYPE', String, "Which service is hosting the folder"
|
6
|
+
|
7
|
+
Datapimp::Cli.accepts_keys_for(c, :amazon, :google, :github, :dropbox)
|
8
|
+
|
9
|
+
c.action do |args, options|
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
command "sync data" do |c|
|
15
|
+
c.description = "Synchronize the contents of a local data store with its remote source"
|
16
|
+
c.syntax = "datapimp sync data [OPTIONS]"
|
17
|
+
|
18
|
+
c.option '--type TYPE', String, "What type of source data is this? #{ Datapimp::Sync.data_source_types.join(", ") }"
|
19
|
+
c.option '--output FILE', String, "Write the output to a file"
|
20
|
+
c.option '--columns NAMES', Array, "Extract only these columns"
|
21
|
+
|
22
|
+
c.example "Syncing an excel file from dropbox ", "datapimp sync data --type dropbox --columns name,description --dropbox-app-key ABC --dropbox-app-secret DEF --dropbox-client-token HIJ --dropbox-client-secret JKL spreadsheets/test.xslx"
|
23
|
+
|
24
|
+
Datapimp::Cli.accepts_keys_for(c, :google, :github, :dropbox)
|
25
|
+
|
26
|
+
c.action do |args, options|
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
data/lib/datapimp/cli.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'launchy'
|
2
|
+
|
3
|
+
module Datapimp
|
4
|
+
module Cli
|
5
|
+
def self.load_commands(from_path=nil)
|
6
|
+
from_path ||= Datapimp.lib.join("datapimp","cli")
|
7
|
+
Dir[from_path.join("**/*.rb")].each {|f| require(f) }
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.accepts_keys_for(c, *services)
|
11
|
+
services.map!(&:to_sym)
|
12
|
+
|
13
|
+
if services.include?(:dropbox)
|
14
|
+
c.option "--dropbox-app-key KEY", String, "The dropbox app key"
|
15
|
+
c.option "--dropbox-app-secret SECRET", String, "The dropbox app secret"
|
16
|
+
c.option "--dropbox-app-sandbox", "The dropbox app is a sandbox app"
|
17
|
+
c.option "--dropbox-client-token TOKEN", String, "The dropbox client token"
|
18
|
+
c.option "--dropbox-client-secret SECRET", String, "The dropbox client secret"
|
19
|
+
c.option "--dropbox-path-prefix PATH", String, "The path prefix for this folder (for sandboxed apps)"
|
20
|
+
end
|
21
|
+
|
22
|
+
if services.include?(:google)
|
23
|
+
c.option "--google-client-id KEY", String, "The google client id"
|
24
|
+
c.option "--google-client-secret KEY", String, "The google client secret"
|
25
|
+
c.option "--google-refresh-token", String, "The google refresh token"
|
26
|
+
c.option "--google-access-token KEY", String, "The google access token"
|
27
|
+
end
|
28
|
+
|
29
|
+
if services.include?(:dnsimple)
|
30
|
+
c.option "--dnsimple-api-token", String, "The DNSimple API Token"
|
31
|
+
c.option "--dnsimple-username", String, "The DNSimple Username"
|
32
|
+
end
|
33
|
+
|
34
|
+
if services.include?(:github)
|
35
|
+
c.option "--github-username", String, "The Github Username"
|
36
|
+
c.option "--github-organization", String, "The Github Organization"
|
37
|
+
c.option "--github-access-token", String, "The Github Personal Access Token"
|
38
|
+
c.option "--github-app-key", String, "The Github App Key"
|
39
|
+
c.option "--github-app-secret", String, "The Github App Secret"
|
40
|
+
end
|
41
|
+
|
42
|
+
if services.include?(:amazon) || services.include?(:aws)
|
43
|
+
c.option '--aws-secret-access-key', String, 'AWS Secret Access Key'
|
44
|
+
c.option '--aws-access-key-id', String, 'AWS Access Key ID'
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|