cloudapp 2.0.0.beta.4 → 2.0.0.beta.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 +12 -19
- data/README.md +60 -6
- data/Rakefile +1 -19
- data/bin/cloudapp +48 -0
- data/cloudapp.gemspec +11 -42
- data/lib/cloudapp/authorized.rb +14 -0
- data/lib/cloudapp/collection_json.rb +86 -3
- data/lib/cloudapp/credentials.rb +115 -0
- data/lib/cloudapp/service.rb +43 -146
- data/lib/cloudapp.rb +1 -3
- data/man/cloudapp.1 +100 -0
- data/man/cloudapp.1.html +157 -0
- data/man/cloudapp.1.ronn +56 -0
- metadata +24 -69
- data/CHANGELOG.md +0 -34
- data/lib/cloudapp/authorized_representation.rb +0 -17
- data/lib/cloudapp/collection_json/item.rb +0 -20
- data/lib/cloudapp/collection_json/representation.rb +0 -74
- data/lib/cloudapp/collection_json/template.rb +0 -17
- data/lib/cloudapp/collection_json/tint.rb +0 -11
- data/lib/cloudapp/drop.rb +0 -37
- data/lib/cloudapp/drop_collection.rb +0 -37
- data/spec/cassettes/account_token.yml +0 -88
- data/spec/cassettes/create_bookmark.yml +0 -132
- data/spec/cassettes/create_bookmark_with_name.yml +0 -133
- data/spec/cassettes/create_bookmark_with_privacy.yml +0 -133
- data/spec/cassettes/list_drops.yml +0 -87
- data/spec/cassettes/list_drops_with_bad_token.yml +0 -45
- data/spec/cassettes/list_drops_with_filter.yml +0 -129
- data/spec/cassettes/list_drops_with_limit.yml +0 -129
- data/spec/cassettes/purge_drops.yml +0 -466
- data/spec/cassettes/setup_drops.yml +0 -620
- data/spec/cassettes/token_for_account.yml +0 -88
- data/spec/cassettes/token_for_account_with_bad_credentials.yml +0 -86
- data/spec/cassettes/upload_file.yml +0 -276
- data/spec/cassettes/upload_file_with_name.yml +0 -278
- data/spec/cassettes/upload_file_with_privacy.yml +0 -277
- data/spec/cassettes/view_drop.yml +0 -45
- data/spec/cloudapp/authorized_representation_spec.rb +0 -32
- data/spec/cloudapp/collection_json/item_spec.rb +0 -45
- data/spec/cloudapp/collection_json/representation_spec.rb +0 -118
- data/spec/cloudapp/collection_json/template_spec.rb +0 -53
- data/spec/cloudapp/drop_collection_spec.rb +0 -127
- data/spec/cloudapp/drop_spec.rb +0 -142
- data/spec/cloudapp/service_spec.rb +0 -335
- data/spec/helper.rb +0 -8
- data/spec/integration_spec.rb +0 -68
- data/spec/support/files/favicon.ico +0 -0
- data/spec/support/stub_class_or_module.rb +0 -22
- data/spec/support/vcr.rb +0 -24
data/Gemfile.lock
CHANGED
@@ -1,22 +1,22 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cloudapp (2.0.0.beta.
|
4
|
+
cloudapp (2.0.0.beta.5)
|
5
5
|
leadlight (~> 0.0.7)
|
6
|
+
netrc (~> 0.7.7)
|
6
7
|
typhoeus (~> 0.3.3)
|
7
8
|
|
8
9
|
GEM
|
9
10
|
remote: http://rubygems.org/
|
10
11
|
specs:
|
11
12
|
addressable (2.2.8)
|
12
|
-
crack (0.3.1)
|
13
|
-
diff-lcs (1.1.3)
|
14
13
|
fail-fast (1.0.0)
|
15
14
|
faraday (0.8.1)
|
16
15
|
multipart-post (~> 1.1)
|
17
16
|
fattr (2.2.1)
|
18
17
|
hookr (1.1.1)
|
19
18
|
fail-fast (= 1.0.0)
|
19
|
+
hpricot (0.8.6)
|
20
20
|
leadlight (0.0.7)
|
21
21
|
addressable (~> 2.2.0)
|
22
22
|
faraday (= 0.8.1)
|
@@ -29,21 +29,16 @@ GEM
|
|
29
29
|
mime-types (1.19)
|
30
30
|
multi_json (1.0.4)
|
31
31
|
multipart-post (1.1.5)
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
rspec-mocks (2.11.2)
|
32
|
+
mustache (0.99.4)
|
33
|
+
netrc (0.7.7)
|
34
|
+
rake (10.0.3)
|
35
|
+
rdiscount (1.6.8)
|
36
|
+
ronn (0.7.3)
|
37
|
+
hpricot (>= 0.8.2)
|
38
|
+
mustache (>= 0.7.0)
|
39
|
+
rdiscount (>= 1.5.8)
|
41
40
|
typhoeus (0.3.3)
|
42
41
|
mime-types
|
43
|
-
vcr (2.0.1)
|
44
|
-
webmock (1.8.9)
|
45
|
-
addressable (>= 2.2.7)
|
46
|
-
crack (>= 0.1.7)
|
47
42
|
|
48
43
|
PLATFORMS
|
49
44
|
ruby
|
@@ -51,6 +46,4 @@ PLATFORMS
|
|
51
46
|
DEPENDENCIES
|
52
47
|
cloudapp!
|
53
48
|
rake
|
54
|
-
|
55
|
-
vcr (~> 2.0.0)
|
56
|
-
webmock
|
49
|
+
ronn
|
data/README.md
CHANGED
@@ -1,14 +1,68 @@
|
|
1
|
-
# CloudApp
|
1
|
+
# CloudApp CLI
|
2
2
|
|
3
|
-
|
3
|
+
Experience all the pleasures of sharing with [CloudApp][] from your terminal.
|
4
|
+
|
5
|
+
[cloudapp]: http://getcloudapp.com
|
4
6
|
|
5
|
-
[cloudapp api]: http://developer.getcloudapp.com
|
6
7
|
|
7
8
|
## Requirements
|
8
9
|
|
9
|
-
`cloudapp` requires Ruby 1.9.2 or greater.
|
10
|
+
`cloudapp` requires Ruby 1.9.2 or greater. Windows is not yet supported. If
|
11
|
+
you're willing to lend a hand, we'd love to officially support it.
|
12
|
+
|
13
|
+
|
14
|
+
## Getting Started
|
15
|
+
|
16
|
+
``` bash
|
17
|
+
$ gem install cloudapp --pre
|
18
|
+
$ cloudapp upload screenshot.png
|
19
|
+
$ cloudapp bookmark http://getcloudapp.com
|
20
|
+
```
|
21
|
+
|
22
|
+
## Commands
|
23
|
+
|
24
|
+
### cloudapp upload
|
25
|
+
|
26
|
+
``` bash
|
27
|
+
$ cloudapp upload screenshot.png
|
28
|
+
http://cl.ly/abc123
|
29
|
+
```
|
30
|
+
|
31
|
+
### cloudapp bookmark
|
32
|
+
|
33
|
+
``` bash
|
34
|
+
$ cloudapp bookmark http://getcloudapp.com
|
35
|
+
http://cl.ly/abc123
|
36
|
+
```
|
37
|
+
|
38
|
+
## Wish List
|
39
|
+
|
40
|
+
A few simple commands to allow scripting and input from other Unix programs
|
41
|
+
would be ideal.
|
42
|
+
|
43
|
+
### Phase: Next
|
44
|
+
|
45
|
+
- Share several files: `cloudapp upload *.png`
|
46
|
+
- Bookmark several links: `cloudapp bookmark http://douglasadams.com http://zombo.com`
|
47
|
+
- Handle bookmarks from STDIN: `pbpaste | cloudapp bookmark`
|
48
|
+
- Handle files from STDIN: `find *.png | cloudapp upload`
|
49
|
+
- Download a drop: `cloudapp download http://cl.ly/abc123`
|
50
|
+
|
51
|
+
### Phase: Unstoppable
|
52
|
+
|
53
|
+
- Archive and share several files: `cloudapp upload --archive *.png`
|
54
|
+
- Encrypt and share a file: `cloudapp upload --encrypt launch_codes.txt`
|
55
|
+
- Download and decrypt and encrypted drop: `cloudapp download --key=def456 http://cl.ly/abc123`
|
56
|
+
|
57
|
+
### Phase: World Domination
|
10
58
|
|
59
|
+
While we're dreaming, what could you do if `cloudapp` had a database of all your
|
60
|
+
drops? Bonus points for a light weight daemon that kept everything in sync at
|
61
|
+
all times.
|
11
62
|
|
12
|
-
|
63
|
+
- Find all your screen shots: `cloudapp list /^screen ?shot.*\.png$/`
|
64
|
+
- Trash all your stale drops: `cloudapp delete --last-viewed="> 1 month ago"`
|
65
|
+
- See your drop views in real time: `cloudapp --tail`
|
13
66
|
|
14
|
-
|
67
|
+
There's bound to be a better way to express some of these commands, but you get
|
68
|
+
the picture.
|
data/Rakefile
CHANGED
@@ -37,24 +37,6 @@ def replace_header(head, header_name)
|
|
37
37
|
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
|
38
38
|
end
|
39
39
|
|
40
|
-
#############################################################################
|
41
|
-
#
|
42
|
-
# Standard tasks
|
43
|
-
#
|
44
|
-
#############################################################################
|
45
|
-
|
46
|
-
require 'rspec'
|
47
|
-
require 'rspec/core/rake_task'
|
48
|
-
|
49
|
-
desc "Run all specs"
|
50
|
-
task RSpec::Core::RakeTask.new('spec')
|
51
|
-
task :default => "spec"
|
52
|
-
|
53
|
-
desc 'Run non-integration specs'
|
54
|
-
RSpec::Core::RakeTask.new('spec:unit') do |t|
|
55
|
-
t.rspec_opts = "--tag ~integration"
|
56
|
-
end
|
57
|
-
|
58
40
|
#############################################################################
|
59
41
|
#
|
60
42
|
# Custom tasks (add your own tasks here)
|
@@ -79,7 +61,7 @@ task :release => :build do
|
|
79
61
|
sh "git tag v#{version}"
|
80
62
|
sh "git push origin master"
|
81
63
|
sh "git push origin v#{version}"
|
82
|
-
sh "gem push pkg/#{
|
64
|
+
sh "gem push pkg/#{gem_file}"
|
83
65
|
end
|
84
66
|
|
85
67
|
desc "Build #{gem_file} into the pkg directory"
|
data/bin/cloudapp
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'cloudapp/credentials'
|
4
|
+
require 'cloudapp/service'
|
5
|
+
|
6
|
+
def service
|
7
|
+
CloudApp::Service.using_token Credentials.token
|
8
|
+
end
|
9
|
+
|
10
|
+
def error error
|
11
|
+
puts "ERROR: #{error}"
|
12
|
+
exit 1
|
13
|
+
end
|
14
|
+
|
15
|
+
def validate_url url
|
16
|
+
error 'URL missing' if url.nil?
|
17
|
+
error "#{ url } doesn't look like a valid URL" unless url =~ URI.regexp
|
18
|
+
end
|
19
|
+
|
20
|
+
def validate_file file
|
21
|
+
error "File doesn't exist" if file.is_a? Errno::ENOENT
|
22
|
+
error 'File missing' if file.nil? or file == STDIN
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
while service.root.unauthorized?
|
27
|
+
Credentials.new.ask_for_and_save_credentials
|
28
|
+
end
|
29
|
+
|
30
|
+
link = ARGV.delete('--direct') || ARGV.delete('-d') ? :embed : :canonical
|
31
|
+
|
32
|
+
case ARGV.shift
|
33
|
+
when 'bookmark'
|
34
|
+
link = :canonical # No such thing as an embed link for a bookmark.
|
35
|
+
url = ARGV.shift
|
36
|
+
validate_url url
|
37
|
+
puts service.bookmark(url).link(link)
|
38
|
+
when 'upload'
|
39
|
+
file = ARGF.file rescue $!
|
40
|
+
validate_file file
|
41
|
+
puts service.upload(file).link(link)
|
42
|
+
else
|
43
|
+
puts <<EOS
|
44
|
+
Usage:
|
45
|
+
cloudapp bookmark http://getcloudapp.com
|
46
|
+
cloudapp upload screenshot.png
|
47
|
+
EOS
|
48
|
+
end
|
data/cloudapp.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
|
|
13
13
|
## If your rubyforge_project name is different, then edit it and comment out
|
14
14
|
## the sub! line in the Rakefile
|
15
15
|
s.name = 'cloudapp'
|
16
|
-
s.version = '2.0.0.beta.
|
17
|
-
s.date = '2012-
|
16
|
+
s.version = '2.0.0.beta.5'
|
17
|
+
s.date = '2012-12-17'
|
18
18
|
s.rubyforge_project = 'cloudapp'
|
19
19
|
|
20
20
|
## Make sure your summary is short. The description may be as long
|
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.require_paths = %w[lib]
|
35
35
|
|
36
36
|
## If your gem includes any executables, list them here.
|
37
|
-
|
37
|
+
s.executables = ["cloudapp"]
|
38
38
|
|
39
39
|
## Specify any RDoc options here. You'll want to add your README and
|
40
40
|
## LICENSE files to the extra_rdoc_files list.
|
@@ -43,66 +43,35 @@ Gem::Specification.new do |s|
|
|
43
43
|
|
44
44
|
## List your runtime dependencies here. Runtime dependencies are those
|
45
45
|
## that are needed for an end user to actually USE your code.
|
46
|
+
s.add_dependency 'netrc', '~> 0.7.7'
|
46
47
|
s.add_dependency 'leadlight', '~> 0.0.7'
|
47
48
|
s.add_dependency 'typhoeus', '~> 0.3.3'
|
48
49
|
|
49
50
|
## List your development dependencies here. Development dependencies are
|
50
51
|
## those that are only needed during development
|
51
52
|
s.add_development_dependency 'rake'
|
52
|
-
s.add_development_dependency '
|
53
|
-
s.add_development_dependency 'vcr', '~> 2.0.0'
|
54
|
-
s.add_development_dependency 'webmock'
|
53
|
+
s.add_development_dependency 'ronn'
|
55
54
|
|
56
55
|
## Leave this section as-is. It will be automatically generated from the
|
57
56
|
## contents of your Git repository via the gemspec task. DO NOT REMOVE
|
58
57
|
## THE MANIFEST COMMENTS, they are used as delimiters by the task.
|
59
58
|
# = MANIFEST =
|
60
59
|
s.files = %w[
|
61
|
-
CHANGELOG.md
|
62
60
|
Gemfile
|
63
61
|
Gemfile.lock
|
64
62
|
MIT-LICENSE
|
65
63
|
README.md
|
66
64
|
Rakefile
|
65
|
+
bin/cloudapp
|
67
66
|
cloudapp.gemspec
|
68
67
|
lib/cloudapp.rb
|
69
|
-
lib/cloudapp/
|
68
|
+
lib/cloudapp/authorized.rb
|
70
69
|
lib/cloudapp/collection_json.rb
|
71
|
-
lib/cloudapp/
|
72
|
-
lib/cloudapp/collection_json/representation.rb
|
73
|
-
lib/cloudapp/collection_json/template.rb
|
74
|
-
lib/cloudapp/collection_json/tint.rb
|
75
|
-
lib/cloudapp/drop.rb
|
76
|
-
lib/cloudapp/drop_collection.rb
|
70
|
+
lib/cloudapp/credentials.rb
|
77
71
|
lib/cloudapp/service.rb
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
spec/cassettes/create_bookmark_with_privacy.yml
|
82
|
-
spec/cassettes/list_drops.yml
|
83
|
-
spec/cassettes/list_drops_with_bad_token.yml
|
84
|
-
spec/cassettes/list_drops_with_filter.yml
|
85
|
-
spec/cassettes/list_drops_with_limit.yml
|
86
|
-
spec/cassettes/purge_drops.yml
|
87
|
-
spec/cassettes/setup_drops.yml
|
88
|
-
spec/cassettes/token_for_account.yml
|
89
|
-
spec/cassettes/token_for_account_with_bad_credentials.yml
|
90
|
-
spec/cassettes/upload_file.yml
|
91
|
-
spec/cassettes/upload_file_with_name.yml
|
92
|
-
spec/cassettes/upload_file_with_privacy.yml
|
93
|
-
spec/cassettes/view_drop.yml
|
94
|
-
spec/cloudapp/authorized_representation_spec.rb
|
95
|
-
spec/cloudapp/collection_json/item_spec.rb
|
96
|
-
spec/cloudapp/collection_json/representation_spec.rb
|
97
|
-
spec/cloudapp/collection_json/template_spec.rb
|
98
|
-
spec/cloudapp/drop_collection_spec.rb
|
99
|
-
spec/cloudapp/drop_spec.rb
|
100
|
-
spec/cloudapp/service_spec.rb
|
101
|
-
spec/helper.rb
|
102
|
-
spec/integration_spec.rb
|
103
|
-
spec/support/files/favicon.ico
|
104
|
-
spec/support/stub_class_or_module.rb
|
105
|
-
spec/support/vcr.rb
|
72
|
+
man/cloudapp.1
|
73
|
+
man/cloudapp.1.html
|
74
|
+
man/cloudapp.1.ronn
|
106
75
|
]
|
107
76
|
# = MANIFEST =
|
108
77
|
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'leadlight'
|
2
|
+
|
3
|
+
module CloudApp
|
4
|
+
module Authorized
|
5
|
+
Tint = Leadlight::Tint.new 'authorized', status: [ :success, 401 ] do
|
6
|
+
extend CloudApp::Authorized::Representation
|
7
|
+
end
|
8
|
+
|
9
|
+
module Representation
|
10
|
+
def unauthorized?() __response__.status == 401 end
|
11
|
+
def authorized?() not unauthorized? end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -1,3 +1,86 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
module CloudApp
|
2
|
+
module CollectionJson
|
3
|
+
Tint = Leadlight::Tint.new 'collection+json', status: [ :success, 401 ] do
|
4
|
+
match_content_type 'application/vnd.collection+json'
|
5
|
+
extend CloudApp::CollectionJson::Representation
|
6
|
+
end
|
7
|
+
|
8
|
+
module Representation
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
def self.extended representation
|
12
|
+
Collection.new(representation).links.each do |link|
|
13
|
+
representation.add_link link.href, link.rel
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def fill_template attributes
|
18
|
+
collection.template.fill(attributes)
|
19
|
+
end
|
20
|
+
|
21
|
+
def collection
|
22
|
+
Collection.new(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def_delegators :collection, :template, :item
|
26
|
+
|
27
|
+
class Item < SimpleDelegator
|
28
|
+
def links
|
29
|
+
fetch('links', []).map {|link| Item.new(link) }
|
30
|
+
end
|
31
|
+
|
32
|
+
def link rel
|
33
|
+
links.find {|link| link.rel == rel.to_s }.href
|
34
|
+
end
|
35
|
+
|
36
|
+
def href() fetch('href') end
|
37
|
+
def rel() fetch('rel') end
|
38
|
+
def data
|
39
|
+
data = {}
|
40
|
+
fetch('data').each do |datum|
|
41
|
+
data[datum.fetch('name')] = datum.fetch('value')
|
42
|
+
end
|
43
|
+
data
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class Collection < Item
|
48
|
+
def initialize representation
|
49
|
+
super representation.fetch('collection')
|
50
|
+
end
|
51
|
+
|
52
|
+
def template() Template.new(fetch('template'), href) end
|
53
|
+
def items
|
54
|
+
fetch('items').map {|item| Item.new(item) }
|
55
|
+
end
|
56
|
+
|
57
|
+
def item
|
58
|
+
items.first
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class Template < Item
|
63
|
+
attr_reader :href
|
64
|
+
|
65
|
+
def initialize item, href
|
66
|
+
@href = href
|
67
|
+
super item
|
68
|
+
end
|
69
|
+
|
70
|
+
def enctype() fetch('enctype') end
|
71
|
+
|
72
|
+
def fill key, value
|
73
|
+
return self unless data.has_key?(key)
|
74
|
+
new_data = fetch('data').map {|datum|
|
75
|
+
if datum.fetch('name') == key
|
76
|
+
datum = datum.merge 'value' => value
|
77
|
+
end
|
78
|
+
datum
|
79
|
+
}
|
80
|
+
new_item = self.merge('data' => new_data)
|
81
|
+
Template.new new_item, href
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# Taken from the heroku gem.
|
2
|
+
# https://github.com/heroku/heroku/blob/master/lib/heroku/auth.rb
|
3
|
+
require 'netrc'
|
4
|
+
|
5
|
+
class Credentials
|
6
|
+
def self.token
|
7
|
+
new.credentials.last
|
8
|
+
end
|
9
|
+
|
10
|
+
def netrc_path
|
11
|
+
default = Netrc.default_path
|
12
|
+
encrypted = default + ".gpg"
|
13
|
+
if File.exists?(encrypted)
|
14
|
+
encrypted
|
15
|
+
else
|
16
|
+
default
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def netrc
|
21
|
+
@netrc ||= begin
|
22
|
+
File.exists?(netrc_path) && Netrc.read(netrc_path)
|
23
|
+
rescue => error
|
24
|
+
if error.message =~ /^Permission bits for/
|
25
|
+
perm = File.stat(netrc_path).mode & 0777
|
26
|
+
abort("Permissions #{perm} for '#{netrc_path}' are too open. You should run `chmod 0600 #{netrc_path}` so that your credentials are NOT accessible by others.")
|
27
|
+
else
|
28
|
+
raise error
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def credentials=(credentials) @credentials = credentials end
|
34
|
+
def credentials()
|
35
|
+
(@credentials ||= read_credentials) || ask_for_and_save_credentials
|
36
|
+
end
|
37
|
+
|
38
|
+
def read_credentials
|
39
|
+
# TODO: convert legacy credentials to netrc
|
40
|
+
# if File.exists?(legacy_credentials_path)
|
41
|
+
# @api, @client = nil
|
42
|
+
# @credentials = File.read(legacy_credentials_path).split("\n")
|
43
|
+
# write_credentials
|
44
|
+
# FileUtils.rm_f(legacy_credentials_path)
|
45
|
+
# end
|
46
|
+
|
47
|
+
# read netrc credentials if they exist
|
48
|
+
self.credentials = netrc['api.getcloudapp.com'] if netrc
|
49
|
+
end
|
50
|
+
|
51
|
+
def write_credentials
|
52
|
+
FileUtils.mkdir_p(File.dirname(netrc_path))
|
53
|
+
FileUtils.touch(netrc_path)
|
54
|
+
FileUtils.chmod(0600, netrc_path)
|
55
|
+
netrc['api.getcloudapp.com'] = credentials
|
56
|
+
netrc.save
|
57
|
+
end
|
58
|
+
|
59
|
+
def delete_credentials
|
60
|
+
# TODO: delete legacy credentials
|
61
|
+
# if File.exists?(legacy_credentials_path)
|
62
|
+
# FileUtils.rm_f(legacy_credentials_path)
|
63
|
+
# end
|
64
|
+
if netrc
|
65
|
+
netrc.delete('api.getcloudapp.com')
|
66
|
+
netrc.save
|
67
|
+
end
|
68
|
+
self.credentials = nil
|
69
|
+
end
|
70
|
+
|
71
|
+
def ask_for_and_save_credentials
|
72
|
+
self.credentials = ask_for_credentials
|
73
|
+
write_credentials
|
74
|
+
credentials
|
75
|
+
end
|
76
|
+
|
77
|
+
def ask_for_credentials
|
78
|
+
puts "Enter your CloudApp credentials."
|
79
|
+
|
80
|
+
print "Email: "
|
81
|
+
email = ask
|
82
|
+
|
83
|
+
print "Password (typing will be hidden): "
|
84
|
+
password = ask_for_password
|
85
|
+
|
86
|
+
# TODO: Remove this dependency on Service.
|
87
|
+
token = CloudApp::Service.token_for_account email, password
|
88
|
+
unless token
|
89
|
+
puts "Incorrect email or password."
|
90
|
+
puts
|
91
|
+
delete_credentials
|
92
|
+
return ask_for_credentials
|
93
|
+
end
|
94
|
+
|
95
|
+
[ email, token ]
|
96
|
+
end
|
97
|
+
|
98
|
+
def ask() $stdin.gets.to_s.strip end
|
99
|
+
def ask_for_password
|
100
|
+
echo_off
|
101
|
+
password = ask
|
102
|
+
puts
|
103
|
+
echo_on
|
104
|
+
return password
|
105
|
+
end
|
106
|
+
|
107
|
+
def echo_on() with_tty { system "stty echo" } end
|
108
|
+
def echo_off() with_tty { system "stty -echo" } end
|
109
|
+
def with_tty(&block)
|
110
|
+
return unless $stdin.isatty
|
111
|
+
yield
|
112
|
+
rescue
|
113
|
+
# fails on windows
|
114
|
+
end
|
115
|
+
end
|