bitballoon 0.1.6 → 0.2.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8c7866ae749fd47feefac0cf704eb56132f41653
4
- data.tar.gz: 02b384fdb2d8d50c2874bcf640c67aa9f0c4656a
3
+ metadata.gz: c588189c9a104f90e2ad87493ceb496ca7d5aa01
4
+ data.tar.gz: 411c2dc541f248a0751e071746a86ae024e46284
5
5
  SHA512:
6
- metadata.gz: 096836497aa39b7f9961eaf243a8a079306dd0d18a3675f4543833a7cf4e1ef15f052d268d974b811430588ccae20bd217e96706de035ce5441361daffbab3d3
7
- data.tar.gz: 62423a9a5781ac034ef06bb0e67426a923927ee5f535224762bc0297bea6001612c5f6171df3872a02586b5a78f3e3670b49474ba10772b685b525772777c221
6
+ metadata.gz: e196e56cd6b436727c08696a9f371eb080d1fe3faa94438a8b56a9a3035f7cbf05c735ebc1a3e52262a8ada9b7fa9c743e44ebf233f001c32ca08be7d86f67d5
7
+ data.tar.gz: 4a81d173863aafac2c6bd2abe669b3f45344d9dd8bf502c70fccae5c0b9fc7d2dffe45f8127bce4d307d3639174f41bcc24c660b8d60351400a1402bbc4415e5
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- bitballoon (0.1.4)
4
+ bitballoon (0.2.0)
5
5
  highline
6
6
  oauth2 (>= 0.9.2)
7
7
  slop
@@ -14,15 +14,14 @@ GEM
14
14
  faraday (0.9.0)
15
15
  multipart-post (>= 1.2, < 3)
16
16
  highline (1.6.21)
17
- jwt (0.1.11)
18
- multi_json (>= 1.5)
17
+ jwt (1.0.0)
19
18
  minitest (5.0.8)
20
- multi_json (1.9.2)
19
+ multi_json (1.10.1)
21
20
  multi_xml (0.5.5)
22
21
  multipart-post (2.0.0)
23
- oauth2 (0.9.3)
22
+ oauth2 (0.9.4)
24
23
  faraday (>= 0.8, < 0.10)
25
- jwt (~> 0.1.8)
24
+ jwt (~> 1.0)
26
25
  multi_json (~> 1.3)
27
26
  multi_xml (~> 0.5)
28
27
  rack (~> 1.2)
data/README.md CHANGED
@@ -28,7 +28,7 @@ or put it in a Gemfile and run `bundle install`
28
28
  Authenticating
29
29
  ==============
30
30
 
31
- You'll need an application client id and a client secret before you can access the BitBalloon API. Please contact us at team@bitballoon.com for your credentials.
31
+ Register a new application at https://www.bitballoon.com/applications to get your Oauth2 secret and key.
32
32
 
33
33
  Once you have your credentials you can instantiate a BitBalloon client.
34
34
 
@@ -41,7 +41,7 @@ Before you can make any requests to the API, you'll need to authenticate with OA
41
41
  If you're authenticating on behalf of a user, you'll need to get a valid access token for that user. Use the BitBalloon client to request an authentication URL:
42
42
 
43
43
  ```ruby
44
- url = bitballoon.authorize_url(:redirect_urai => "http://www.example.com/callback")
44
+ url = bitballoon.authorize_url(:redirect_uri => "http://www.example.com/callback")
45
45
  ```
46
46
 
47
47
  The user then visits that URL and will be prompted to authorize your application to access his BitBalloon sites. If she grants permission, she'll be redirected back to the `redirect_uri` provided in the `authorize_url` call. This URL must match the redirect url configured for your BitBalloon application. Once the user comes back to your app, you'll be able to access a `code` query parameter that gives you an authorization code. Use this to finish the OAuth2 flow:
@@ -132,17 +132,13 @@ Creating a site from a zip file:
132
132
  site = bitballoon.sites.create(:zip => "/tmp/my-site.zip")
133
133
  ```
134
134
 
135
- Both methods will create the site and upload the files. The site will then be processing.
135
+ Both methods will create the site and upload the files to a new deploy.
136
136
 
137
- ```ruby
138
- site.state == "processing"
139
- site.processing? == true
140
- ```
141
-
142
- Refresh a site to update the state:
137
+ Creating a site with a dir or a zip is actually a shortcut for something like this:
143
138
 
144
139
  ```ruby
145
- site.refresh
140
+ site = bitballoon.sites.create(:name => "unique-site-subdomain", :custom_domain => "www.example.com")
141
+ deploy = site.deploys.create(:dir => "path/to/my-site")
146
142
  ```
147
143
 
148
144
  Use `wait_for_ready` to wait until a site has finished processing.
@@ -153,20 +149,29 @@ site.wait_for_ready
153
149
  site.state == "ready"
154
150
  ```
155
151
 
152
+ This also works on a specific deploy, and you can pass in a block to execute after each polling action:
153
+
154
+ ```ruby
155
+ deploy = site.deploys.create(:dir => "/tmp/my-site")
156
+ deploy.wait_for_ready do |deploy|
157
+ puts "Current state: #{deploy.state}"
158
+ end
159
+ ```
160
+
156
161
  Redeploy a site from a dir:
157
162
 
158
163
  ```ruby
159
164
  site = bitballoon.sites.get(site_id)
160
- site.update(:dir => "/tmp/my-site")
161
- site.wait_for_ready
165
+ deploy = site.deploys.create(:dir => "/tmp/my-site")
166
+ deploy.wait_for_ready
162
167
  ```
163
168
 
164
169
  Redeploy a site from a zip file:
165
170
 
166
171
  ```ruby
167
172
  site = bitballoon.sites.get(site_id)
168
- site.update(:zip => "/tmp/my-site.zip")
169
- site.wait_for_ready
173
+ deploy = site.deploys.create(:zip => "/tmp/my-site.zip")
174
+ deploy.wait_for_ready
170
175
  ```
171
176
 
172
177
  Update the name of the site (its subdomain), the custom domain and the notification email for form submissions:
@@ -195,7 +200,7 @@ Access a specific deploy
195
200
 
196
201
  ```ruby
197
202
  site = bitballoon.sites.get(site_id)
198
- site.deploys.get(id)
203
+ deploy = site.deploys.get(id)
199
204
  ```
200
205
 
201
206
  Restore a deploy (makes it the current live version of the site)
@@ -204,6 +209,12 @@ Restore a deploy (makes it the current live version of the site)
204
209
  site.deploys.get(id).restore
205
210
  ```
206
211
 
212
+ Create a new deploy
213
+
214
+ ```ruby
215
+ deploy = site.deploys.create(:dir => "/tmp/my-site")
216
+ ```
217
+
207
218
  Users
208
219
  =====
209
220
 
@@ -427,4 +438,3 @@ Revoke access token:
427
438
  ```ruby
428
439
  bitballoon.access_tokens.get("token-string").destroy
429
440
  ```
430
-
@@ -65,4 +65,4 @@ opts = Slop.parse do
65
65
  puts "Site deployed: #{site.url}"
66
66
  end
67
67
  end
68
- end
68
+ end
@@ -45,4 +45,4 @@ module BitBalloon
45
45
  [prefix, self.class.path].compact.join("/")
46
46
  end
47
47
  end
48
- end
48
+ end
@@ -4,10 +4,54 @@ module BitBalloon
4
4
  :admin_url, :deploy_url, :screenshot_url, :created_at, :updated_at,
5
5
  :user_id, :required
6
6
 
7
+ def upload_dir(dir)
8
+ return unless state == "uploading"
9
+
10
+ shas = Hash.new { [] }
11
+ glob = ::File.join(dir, "**", "*")
12
+
13
+ Dir.glob(glob) do |file|
14
+ next unless ::File.file?(file)
15
+ pathname = ::File.join("/", file[dir.length..-1])
16
+ next if pathname.match(/(^\/?__MACOSX\/|\/\.)/)
17
+ sha = Digest::SHA1.hexdigest(::File.read(file))
18
+ shas[sha] = shas[sha] + [pathname]
19
+ end
20
+
21
+ (required || []).each do |sha|
22
+ shas[sha].each do |pathname|
23
+ client.request(:put, ::File.join(path, "files", URI.encode(pathname)), :body => ::File.read(::File.join(dir, pathname)), :headers => {"Content-Type" => "application/octet-stream"})
24
+ end
25
+ end
26
+
27
+ refresh
28
+ end
29
+
30
+ def wait_for_ready(timeout = 900)
31
+ start = Time.now
32
+ while !(ready?)
33
+ sleep 5
34
+ refresh
35
+ puts "Got state: #{state}"
36
+ raise "Error processing site: #{error_message}" if error?
37
+ yield(self) if block_given?
38
+ raise "Timeout while waiting for ready" if Time.now - start > timeout
39
+ end
40
+ self
41
+ end
42
+
43
+ def ready?
44
+ state == "ready"
45
+ end
46
+
47
+ def error?
48
+ state == "error"
49
+ end
50
+
7
51
  def restore
8
52
  response = client.request(:post, ::File.join(path, "restore"))
9
53
  process(response.parsed)
10
54
  self
11
55
  end
12
56
  end
13
- end
57
+ end
@@ -3,5 +3,36 @@ require "bitballoon/deploy"
3
3
  module BitBalloon
4
4
  class Deploys < CollectionProxy
5
5
  path "/deploys"
6
+
7
+ def create(attributes)
8
+ if attributes[:dir]
9
+ response = client.request(:post, path,
10
+ :body => JSON.generate({:files => inventory(attributes[:dir])}),
11
+ :headers => {"Content-Type" => "application/json"}
12
+ )
13
+ Deploy.new(client, response.parsed).tap do |deploy|
14
+ deploy.upload_dir(attributes[:dir])
15
+ end
16
+ elsif attributes[:zip]
17
+ response = client.request(:post, path,
18
+ :body => ::File.read(attributes[:zip]),
19
+ :headers => {"Content-Type" => "application/zip"}
20
+ )
21
+ Deploy.new(client, response.parsed)
22
+ else
23
+ raise "Need dir or zip to create a deploy"
24
+ end
25
+ end
26
+
27
+ private
28
+ def inventory(dir)
29
+ files = {}
30
+ Dir[::File.join(dir, "**", "*")].each do |file|
31
+ next unless ::File.file?(file)
32
+ path = ::File.join("/", file[dir.length..-1])
33
+ files[path] = Digest::SHA1.hexdigest(::File.read(file))
34
+ end
35
+ files
36
+ end
6
37
  end
7
- end
38
+ end
@@ -4,32 +4,8 @@ require 'uri'
4
4
  module BitBalloon
5
5
  class Site < Model
6
6
  fields :id, :state, :premium, :claimed, :name, :custom_domain, :url,
7
- :admin_url, :deploy_url, :screenshot_url, :created_at, :updated_at,
8
- :password, :notification_email, :user_id, :required, :error_message
9
-
10
- def upload_dir(dir)
11
- return unless state == "uploading"
12
-
13
- shas = Hash.new { [] }
14
- glob = ::File.join(dir, "**", "*")
15
-
16
- Dir.glob(glob) do |file|
17
- next unless ::File.file?(file)
18
- pathname = ::File.join("/", file[dir.length..-1])
19
- next if pathname.match(/(^\/?__MACOSX\/|\/\.)/)
20
- sha = Digest::SHA1.hexdigest(::File.read(file))
21
- shas[sha] = shas[sha] + [pathname]
22
- end
23
-
24
-
25
- (required || []).each do |sha|
26
- shas[sha].each do |pathname|
27
- client.request(:put, ::File.join(path, "files", URI.encode(pathname)), :body => ::File.read(::File.join(dir, pathname)), :headers => {"Content-Type" => "application/octet-stream"})
28
- end
29
- end
30
-
31
- refresh
32
- end
7
+ :admin_url, :deploy_id, :deploy_url, :screenshot_url, :created_at, :updated_at,
8
+ :password, :notification_email, :user_id, :error_message, :required
33
9
 
34
10
  def ready?
35
11
  state == "current"
@@ -39,25 +15,19 @@ module BitBalloon
39
15
  state == "error"
40
16
  end
41
17
 
42
- def wait_for_ready(timeout = 900)
43
- start = Time.now
44
- while !(ready?)
45
- sleep 5
46
- refresh
47
- raise "Error processing site: #{error_message}" if error?
48
- yield(self) if block_given?
49
- raise "Timeout while waiting for ready" if Time.now - start > timeout
50
- end
18
+ def wait_for_ready(timeout = 900, &block)
19
+ deploy = deploys.get(deploy_id)
20
+ raise "Error fetching deploy #{deploy_id}" unless deploy
21
+ deploy.wait_for_ready(timeout, &block)
51
22
  self
52
23
  end
53
24
 
54
25
  def update(attributes)
26
+ response = client.request(:put, path, :body => mutable_attributes(attributes))
27
+ process(response.parsed)
55
28
  if attributes[:zip] || attributes[:dir]
56
- site = collection.new(client).create(attributes.merge(:id => id))
57
- process(site.attributes)
58
- else
59
- response = client.request(:put, path, :body => mutable_attributes(attributes))
60
- process(response.parsed)
29
+ deploy = deploys.create(attributes)
30
+ self.deploy_id = deploy.id
61
31
  end
62
32
  self
63
33
  end
@@ -6,35 +6,13 @@ module BitBalloon
6
6
  path "/sites"
7
7
 
8
8
  def create(attributes = {})
9
- site_id = attributes.delete(:id)
10
- path = site_id ? "/sites/#{site_id}" : "/sites"
11
- method = site_id ? :put : :post
12
- if attributes[:dir]
13
- dir = attributes.delete(:dir)
14
- response = client.request(method, path, :body => JSON.generate(attributes.merge(:files => inventory(dir))), :headers => {"Content-Type" => "application/json"})
15
- Site.new(client, response.parsed).tap do |site|
16
- site.upload_dir(dir)
9
+ response = client.request(:post, path, :body => Site.new(client, {}).send(:mutable_attributes, attributes))
10
+ Site.new(client, response.parsed).tap do |site|
11
+ if attributes[:zip] || attributes[:dir]
12
+ deploy = site.deploys.create(attributes)
13
+ site.deploy_id = deploy.id
17
14
  end
18
- elsif attributes[:zip]
19
- zip = attributes.delete(:zip)
20
- ::File.open(zip) do |file|
21
- response = client.request(method, path, :body => attributes.merge(
22
- :zip => Faraday::UploadIO.new(file, 'application/zip')
23
- ))
24
- Site.new(client, response.parsed)
25
- end
26
- end
27
- end
28
-
29
- private
30
- def inventory(dir)
31
- files = {}
32
- Dir[::File.join(dir, "**", "*")].each do |file|
33
- next unless ::File.file?(file)
34
- path = ::File.join("/", file[dir.length..-1])
35
- files[path] = Digest::SHA1.hexdigest(::File.read(file))
36
15
  end
37
- files
38
16
  end
39
17
  end
40
- end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module BitBalloon
2
- VERSION = "0.1.6"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -17,23 +17,29 @@ class SitesTest < MiniTest::Unit::TestCase
17
17
  index_sha = Digest::SHA1.hexdigest(::File.read(::File.join(dir, "index.html")))
18
18
 
19
19
  stub_request(:post, "https://www.bitballoon.com/api/v1/sites")
20
+ .to_return {|request|
21
+ {
22
+ :headers => {'Content-Type' => 'application/json'},
23
+ :body => JSON.generate({:id => "1234"})
24
+ }
25
+ }
26
+ stub_request(:post, "https://www.bitballoon.com/api/v1/sites/1234/deploys")
20
27
  .to_return {|request|
21
28
  body = JSON.parse(request.body)
22
29
  {
23
30
  :headers => {'Content-Type' => 'application/json'},
24
- :body => JSON.generate({:id => "1234", :state => "uploading", :required => [index_sha]})
31
+ :body => JSON.generate({:id => "2345", :state => "uploading", :required => [index_sha]})
25
32
  }
26
33
  }
27
- stub_request(:put, "https://www.bitballoon.com/api/v1/sites/1234/files/index.html")
28
- stub_request(:get, "https://www.bitballoon.com/api/v1/sites/1234")
29
- .to_return(:headers => {'Content-Type' => 'application/json'}, :body => {:id => "1234", :state => "processing"})
34
+ stub_request(:put, "https://www.bitballoon.com/api/v1/deploys/2345/files/index.html")
35
+ stub_request(:get, "https://www.bitballoon.com/api/v1/deploys/2345")
36
+ .to_return(:headers => {'Content-Type' => 'application/json'}, :body => {:id => "2345", :state => "processing"})
30
37
 
31
38
  site = client.sites.create(:dir => dir)
32
39
 
33
- assert_equal 'processing', site.state
34
40
  assert_equal index_sha, body['files']['/index.html']
35
41
 
36
- assert_requested :put, "https://www.bitballoon.com/api/v1/sites/1234/files/index.html",
42
+ assert_requested :put, "https://www.bitballoon.com/api/v1/deploys/2345/files/index.html",
37
43
  :body => ::File.read(::File.join(dir, "index.html")), :times => 1 # ===> Success
38
44
  end
39
45
 
@@ -41,12 +47,20 @@ class SitesTest < MiniTest::Unit::TestCase
41
47
  stub_request(:post, "https://www.bitballoon.com/api/v1/sites")
42
48
  .to_return({
43
49
  :headers => {'Content-Type' => 'application/json'},
44
- :body => JSON.generate({:id => "1234", :state => "processing", :required => []})
50
+ :body => JSON.generate({:id => "1234"})
45
51
  })
46
52
 
53
+ stub_request(:post, "https://www.bitballoon.com/api/v1/sites/1234/deploys")
54
+ .to_return {|request|
55
+ {
56
+ :headers => {'Content-Type' => 'application/json'},
57
+ :body => JSON.generate({:id => "2345", :state => "uploading", :required => []})
58
+ }
59
+ }
47
60
  zip = ::File.expand_path("../files/site-dir.zip", __FILE__)
48
61
  site = client.sites.create(:zip => zip)
49
62
 
50
- assert_equal 'processing', site.state
63
+ assert_requested :post, "https://www.bitballoon.com/api/v1/sites/1234/deploys",
64
+ :body => ::File.read(zip), :times => 1
51
65
  end
52
- end
66
+ end
metadata CHANGED
@@ -1,83 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitballoon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mathias Biilmann Christensen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-21 00:00:00.000000000 Z
11
+ date: 2014-06-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: oauth2
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.9.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.9.2
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: slop
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: highline
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
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
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: minitest
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: webmock
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  description: API Client for BitBalloon
@@ -136,17 +136,17 @@ require_paths:
136
136
  - lib
137
137
  required_ruby_version: !ruby/object:Gem::Requirement
138
138
  requirements:
139
- - - ">="
139
+ - - '>='
140
140
  - !ruby/object:Gem::Version
141
141
  version: '0'
142
142
  required_rubygems_version: !ruby/object:Gem::Requirement
143
143
  requirements:
144
- - - ">="
144
+ - - '>='
145
145
  - !ruby/object:Gem::Version
146
146
  version: '0'
147
147
  requirements: []
148
148
  rubyforge_project:
149
- rubygems_version: 2.2.2
149
+ rubygems_version: 2.0.2
150
150
  signing_key:
151
151
  specification_version: 4
152
152
  summary: API Client for BitBalloon