bitballoon 0.0.4 → 0.0.5
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/Gemfile.lock +1 -1
- data/README.md +52 -11
- data/bin/bitballoon +21 -10
- data/lib/bitballoon.rb +1 -0
- data/lib/bitballoon/client.rb +25 -1
- data/lib/bitballoon/deploy.rb +13 -0
- data/lib/bitballoon/deploys.rb +7 -0
- data/lib/bitballoon/model.rb +1 -1
- data/lib/bitballoon/site.rb +16 -6
- data/lib/bitballoon/sites.rb +5 -2
- data/lib/bitballoon/version.rb +1 -1
- metadata +4 -2
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -46,40 +46,65 @@ If you're not authenticating on behalf of a user you can authorize directly with
|
|
46
46
|
bitballoon.authorize_from_credentials!
|
47
47
|
```
|
48
48
|
|
49
|
+
Command Line Utility
|
50
|
+
====================
|
51
|
+
|
52
|
+
The BitBalloon gem comes with a handy command line utility for deploying and redeploying sites.
|
53
|
+
|
54
|
+
To deploy the site in the current working directory:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
bitballoon deploy
|
58
|
+
```
|
59
|
+
|
60
|
+
The first time you deploy, you will be asked for your `client id` and `client secret`. After the deploy the tool will store an `access_token` and the `site_id` in `.bitballoon`. Next time you run the command the tool will redeploy the site using the stored `access_token`.
|
61
|
+
|
62
|
+
You can also deploy a specific path:
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
bitballoon deploy /path/to/my/site
|
66
|
+
```
|
67
|
+
|
68
|
+
Or a zip file:
|
69
|
+
|
70
|
+
```ruby
|
71
|
+
bitballoon deploy /path/to/my/site.zip
|
72
|
+
```
|
73
|
+
|
49
74
|
Sites
|
50
75
|
=====
|
51
76
|
|
52
77
|
Getting a list of all sites you have access to:
|
53
78
|
|
54
79
|
```ruby
|
55
|
-
|
56
|
-
|
57
|
-
|
80
|
+
bitballoon.sites.each do |site|
|
81
|
+
puts site.url
|
82
|
+
end
|
58
83
|
```
|
59
84
|
|
60
85
|
Getting a specific site by id:
|
61
86
|
|
62
87
|
```ruby
|
63
|
-
|
88
|
+
site = bitballoon.sites.get(id)
|
64
89
|
```
|
65
90
|
|
66
91
|
Creating a site from a directory:
|
67
92
|
|
68
93
|
```ruby
|
69
|
-
|
94
|
+
site = bitballoon.sites.create(:dir => "/tmp/my-site")
|
70
95
|
```
|
71
96
|
|
72
97
|
Creating a site from a zip file:
|
73
98
|
|
74
99
|
```ruby
|
75
|
-
|
100
|
+
site = bitballoon.sites.create(:zip => "/tmp/my-site.zip")
|
76
101
|
```
|
77
102
|
|
78
103
|
Both methods will create the site and upload the files. The site will then be processing.
|
79
104
|
|
80
105
|
```ruby
|
81
|
-
|
82
|
-
|
106
|
+
site.state == "processing"
|
107
|
+
site.processing? == true
|
83
108
|
```
|
84
109
|
|
85
110
|
Refresh a site to update the state:
|
@@ -91,9 +116,25 @@ Refresh a site to update the state:
|
|
91
116
|
Use `wait_until_ready` to wait until a site has finished processing.
|
92
117
|
|
93
118
|
```ruby
|
94
|
-
|
95
|
-
|
96
|
-
|
119
|
+
site = bitballoon.sites.create(:dir => "/tmp/my-site")
|
120
|
+
site.wait_for_ready
|
121
|
+
site.state == "ready"
|
122
|
+
```
|
123
|
+
|
124
|
+
Redeploy a site from a dir:
|
125
|
+
|
126
|
+
```ruby
|
127
|
+
site = bitballoon.sites.get(site_id)
|
128
|
+
site.update(:dir => "/tmp/my-site")
|
129
|
+
site.wait_for_ready
|
130
|
+
```
|
131
|
+
|
132
|
+
Redeploy a site from a zip file:
|
133
|
+
|
134
|
+
```ruby
|
135
|
+
site = bitballoon.sites.get(site_id)
|
136
|
+
site.update(:zip => "/tmp/my-site.zip")
|
137
|
+
site.wait_for_ready
|
97
138
|
```
|
98
139
|
|
99
140
|
Update the name of the site (its subdomain), the custom domain and the notification email for form submissions:
|
data/bin/bitballoon
CHANGED
@@ -12,33 +12,44 @@ opts = Slop.parse do
|
|
12
12
|
command 'deploy' do
|
13
13
|
run do |opts, args|
|
14
14
|
path = args.first ? File.expand_path(args.first) : Dir.getwd
|
15
|
+
zip = path.match(/\.zip$/)
|
15
16
|
|
16
17
|
raise "File or dir doesn't exist: #{path}" unless File.exist?(path)
|
17
|
-
raise "Can't deploy a single file" if File.file?(path) && !
|
18
|
+
raise "Can't deploy a single file" if File.file?(path) && !zip
|
18
19
|
|
20
|
+
credentials_path = File.expand_path(".bitballoon", zip ? File.dirname(path) : path)
|
19
21
|
|
20
|
-
|
21
|
-
credentials_path = File.exist?(File.expand_path(".bitballoon")) ? File.expand_path(".bitballoon") : "#{Dir.home}/.bitballoon"
|
22
22
|
if File.exist?(credentials_path)
|
23
|
-
|
24
|
-
client = BitBalloon::Client.new(:access_token => access_token)
|
23
|
+
credentials = JSON.parse(File.read(credentials_path))
|
24
|
+
client = BitBalloon::Client.new(:access_token => credentials['access_token'])
|
25
25
|
else
|
26
26
|
puts "Please enter your BitBalloon API Credentials (if you don't have any, you can create your credentials at https://www.bitballoon.com/applications)"
|
27
27
|
client_id = ask("Client ID:")
|
28
28
|
client_secret = ask("Client Secret:")
|
29
29
|
client = BitBalloon::Client.new(:client_id => client_id, :client_secret => client_secret)
|
30
30
|
client.authorize_from_credentials!
|
31
|
-
|
32
|
-
file.write(JSON.generate(:access_token => client.access_token))
|
33
|
-
end
|
34
|
-
puts "Wrote access token to '#{credentials_path}'"
|
31
|
+
credentials = {'access_token' => client.access_token}
|
35
32
|
end
|
36
33
|
|
37
|
-
|
34
|
+
attributes = zip ? {:zip => path} : {:dir => path}
|
35
|
+
|
36
|
+
if credentials['site_id']
|
37
|
+
site = client.sites.get(credentials['site_id'])
|
38
|
+
site.update(attributes)
|
39
|
+
else
|
40
|
+
site = client.sites.create(attributes)
|
41
|
+
end
|
38
42
|
puts "Waiting for processing"
|
39
43
|
site.wait_for_ready do |site|
|
40
44
|
puts "Polling site: #{site.id} - #{site.state}"
|
41
45
|
end
|
46
|
+
|
47
|
+
credentials['site_id'] = site.id
|
48
|
+
|
49
|
+
File.open(credentials_path, "w") do |file|
|
50
|
+
file.write(JSON.generate(credentials))
|
51
|
+
end
|
52
|
+
|
42
53
|
puts "Site deployed: #{site.url}"
|
43
54
|
end
|
44
55
|
end
|
data/lib/bitballoon.rb
CHANGED
data/lib/bitballoon/client.rb
CHANGED
@@ -5,6 +5,12 @@ module BitBalloon
|
|
5
5
|
ENDPOINT = ENV['OAUTH_CLIENT_API_URL'] || 'https://www.bitballoon.com'
|
6
6
|
API_VERSION = "v1"
|
7
7
|
|
8
|
+
class BitBalloonError < StandardError; end
|
9
|
+
class NotFoundError < BitBalloonError; end
|
10
|
+
class ConnectionError < BitBalloonError; end
|
11
|
+
class InternalServerError < BitBalloonError; end
|
12
|
+
class AuthenticationError < BitBalloonError; end
|
13
|
+
|
8
14
|
attr_accessor :client_id, :client_secret, :oauth, :access_token
|
9
15
|
|
10
16
|
def initialize(options)
|
@@ -45,13 +51,31 @@ module BitBalloon
|
|
45
51
|
end
|
46
52
|
|
47
53
|
def request(verb, path, opts={}, &block)
|
48
|
-
raise "Authorize with BitBalloon before making requests" unless oauth_token
|
54
|
+
raise AuthenticationError, "Authorize with BitBalloon before making requests" unless oauth_token
|
55
|
+
|
49
56
|
oauth_token.request(verb, ::File.join("/api", API_VERSION, path), opts, &block)
|
57
|
+
rescue OAuth2::Error => e
|
58
|
+
case e.response.status
|
59
|
+
when 401
|
60
|
+
raise AuthenticationError, message_for(e, "Authentication Error")
|
61
|
+
when 404
|
62
|
+
raise NotFoundError, message_for(e, "Not Found")
|
63
|
+
when 500
|
64
|
+
raise InternalServerError, message_for(e, "Internal Server Error")
|
65
|
+
else
|
66
|
+
raise BitBalloonError, message_for(e, "OAuth2 Error")
|
67
|
+
end
|
68
|
+
rescue Faraday::Error::ConnectionFailed => e
|
69
|
+
raise ConnectionError, message_for(e, "Connection Error")
|
50
70
|
end
|
51
71
|
|
52
72
|
private
|
53
73
|
def oauth_token
|
54
74
|
@oauth_token ||= access_token && OAuth2::AccessToken.new(oauth, access_token)
|
55
75
|
end
|
76
|
+
|
77
|
+
def message_for(error, default)
|
78
|
+
error.message.strip == "" ? default : error.message
|
79
|
+
end
|
56
80
|
end
|
57
81
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module BitBalloon
|
2
|
+
class Deploy < Model
|
3
|
+
fields :id, :state, :premium, :claimed, :name, :custom_domain, :url,
|
4
|
+
:admin_url, :deploy_url, :screenshot_url, :created_at, :updated_at,
|
5
|
+
:user_id, :required
|
6
|
+
|
7
|
+
def restore
|
8
|
+
response = client.request(:post, File.join(path, "restore"))
|
9
|
+
process(response.parsed)
|
10
|
+
self
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/lib/bitballoon/model.rb
CHANGED
data/lib/bitballoon/site.rb
CHANGED
@@ -3,8 +3,8 @@ require 'digest/sha1'
|
|
3
3
|
module BitBalloon
|
4
4
|
class Site < Model
|
5
5
|
fields :id, :state, :premium, :claimed, :name, :custom_domain, :url,
|
6
|
-
:admin_url, :screenshot_url, :created_at, :updated_at,
|
7
|
-
:required
|
6
|
+
:admin_url, :deploy_url, :screenshot_url, :created_at, :updated_at,
|
7
|
+
:user_id, :required, :error_message
|
8
8
|
|
9
9
|
def upload_dir(dir)
|
10
10
|
return unless state == "uploading"
|
@@ -25,14 +25,19 @@ module BitBalloon
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def ready?
|
28
|
-
state == "
|
28
|
+
state == "current"
|
29
|
+
end
|
30
|
+
|
31
|
+
def error?
|
32
|
+
state == "error"
|
29
33
|
end
|
30
34
|
|
31
35
|
def wait_for_ready(timeout = 900)
|
32
36
|
start = Time.now
|
33
|
-
while !ready?
|
37
|
+
while !(ready?)
|
34
38
|
sleep 5
|
35
39
|
refresh
|
40
|
+
raise "Error processing site: #{error_message}" if error?
|
36
41
|
yield(self) if block_given?
|
37
42
|
raise "Timeout while waiting for ready" if Time.now - start > timeout
|
38
43
|
end
|
@@ -40,8 +45,13 @@ module BitBalloon
|
|
40
45
|
end
|
41
46
|
|
42
47
|
def update(attributes)
|
43
|
-
|
44
|
-
|
48
|
+
if attributes[:zip] || attributes[:dir]
|
49
|
+
site = collection.new(client).create(attributes.merge(:id => id))
|
50
|
+
process(site.attributes)
|
51
|
+
else
|
52
|
+
response = client.request(:put, path, :body => mutable_attributes(attributes))
|
53
|
+
process(response.parsed)
|
54
|
+
end
|
45
55
|
self
|
46
56
|
end
|
47
57
|
|
data/lib/bitballoon/sites.rb
CHANGED
@@ -6,15 +6,18 @@ 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
|
9
12
|
if attributes[:dir]
|
10
13
|
dir = attributes[:dir]
|
11
|
-
response = client.request(
|
14
|
+
response = client.request(method, path, :body => JSON.generate({:files => inventory(dir)}), :headers => {"Content-Type" => "application/json"})
|
12
15
|
Site.new(client, response.parsed).tap do |site|
|
13
16
|
site.upload_dir(dir)
|
14
17
|
end
|
15
18
|
elsif attributes[:zip]
|
16
19
|
::File.open(attributes[:zip]) do |file|
|
17
|
-
response = client.request(
|
20
|
+
response = client.request(method, path, :body => {
|
18
21
|
:zip => Faraday::UploadIO.new(file, 'application/zip')
|
19
22
|
})
|
20
23
|
Site.new(client, response.parsed)
|
data/lib/bitballoon/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bitballoon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-10-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: oauth2
|
@@ -109,6 +109,8 @@ files:
|
|
109
109
|
- lib/bitballoon.rb
|
110
110
|
- lib/bitballoon/client.rb
|
111
111
|
- lib/bitballoon/collection_proxy.rb
|
112
|
+
- lib/bitballoon/deploy.rb
|
113
|
+
- lib/bitballoon/deploys.rb
|
112
114
|
- lib/bitballoon/file.rb
|
113
115
|
- lib/bitballoon/files.rb
|
114
116
|
- lib/bitballoon/form.rb
|