bitballoon 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|