cloudapp 1.1.0 → 2.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +3 -0
- data/Gemfile.lock +18 -34
- data/README.md +2 -1
- data/Rakefile +5 -1
- data/cloudapp.gemspec +50 -41
- data/lib/cloudapp/account.rb +111 -0
- data/lib/cloudapp/authorized_representation.rb +17 -0
- data/lib/cloudapp/collection_json/item.rb +20 -0
- data/lib/cloudapp/collection_json/representation.rb +74 -0
- data/lib/cloudapp/collection_json/template.rb +17 -0
- data/lib/cloudapp/collection_json/tint.rb +11 -0
- data/lib/cloudapp/collection_json.rb +3 -0
- data/lib/cloudapp/drop.rb +22 -6
- data/lib/cloudapp/drop_collection.rb +22 -0
- data/lib/cloudapp/service.rb +172 -0
- data/lib/cloudapp/token.rb +27 -0
- data/lib/cloudapp.rb +5 -1
- data/man/cloudapp.1 +202 -45
- data/man/cloudapp.1.html +114 -42
- data/man/cloudapp.1.ronn +125 -45
- data/spec/cassettes/create_bookmark.yml +255 -0
- data/spec/cassettes/create_bookmark_with_name.yml +266 -0
- data/spec/cassettes/create_bookmark_with_privacy.yml +277 -0
- data/spec/cassettes/delete_drop.yml +383 -0
- data/spec/cassettes/list_drops.yml +139 -0
- data/spec/cassettes/list_drops_with_bad_token.yml +57 -0
- data/spec/cassettes/list_drops_with_filter.yml +209 -0
- data/spec/cassettes/list_drops_with_href.yml +287 -0
- data/spec/cassettes/list_drops_with_href_and_filter.yml +287 -0
- data/spec/cassettes/list_drops_with_href_and_limit.yml +287 -0
- data/spec/cassettes/list_drops_with_limit.yml +211 -0
- data/spec/cassettes/list_drops_with_nil_href.yml +139 -0
- data/spec/cassettes/purge_drops.yml +1103 -0
- data/spec/cassettes/recover_drop.yml +628 -0
- data/spec/cassettes/rename_drop.yml +367 -0
- data/spec/cassettes/setup_drops.yml +968 -0
- data/spec/cassettes/token_for_account.yml +127 -0
- data/spec/cassettes/token_for_account_with_bad_credentials.yml +115 -0
- data/spec/cassettes/trash_drop.yml +478 -0
- data/spec/cassettes/update_drop_bookmark_url.yml +379 -0
- data/spec/cassettes/update_file.yml +573 -0
- data/spec/cassettes/upload_file.yml +470 -0
- data/spec/cassettes/upload_file_with_name.yml +484 -0
- data/spec/cassettes/upload_file_with_privacy.yml +495 -0
- data/spec/cassettes/view_drop.yml +73 -0
- data/spec/cloudapp/account_spec.rb +166 -0
- data/spec/cloudapp/authorized_representation_spec.rb +32 -0
- data/spec/cloudapp/collection_json/item_spec.rb +45 -0
- data/spec/cloudapp/collection_json/representation_spec.rb +118 -0
- data/spec/cloudapp/collection_json/template_spec.rb +53 -0
- data/spec/cloudapp/drop_collection_spec.rb +63 -0
- data/spec/cloudapp/drop_spec.rb +81 -51
- data/spec/cloudapp/service_spec.rb +357 -0
- data/spec/cloudapp/token_spec.rb +33 -0
- data/spec/integration_spec.rb +100 -0
- data/spec/support/stub_class_or_module.rb +6 -3
- data/spec/support/vcr.rb +21 -5
- metadata +84 -106
- data/bin/cloudapp +0 -184
- data/lib/cloudapp/config.rb +0 -39
- data/lib/cloudapp/drop_content.rb +0 -34
- data/lib/cloudapp/drop_presenter.rb +0 -80
- data/lib/cloudapp/drop_service.rb +0 -255
- data/lib/cloudapp/identity.rb +0 -14
- data/spec/cassettes/DropContent/download.yml +0 -116
- data/spec/cassettes/DropService/create_bookmark.yml +0 -105
- data/spec/cassettes/DropService/create_bookmark_with_bad_credentials.yml +0 -39
- data/spec/cassettes/DropService/create_bookmark_with_name.yml +0 -105
- data/spec/cassettes/DropService/create_private_bookmark.yml +0 -105
- data/spec/cassettes/DropService/create_public_bookmark.yml +0 -105
- data/spec/cassettes/DropService/drop.yml +0 -81
- data/spec/cassettes/DropService/list_drops.yml +0 -135
- data/spec/cassettes/DropService/list_drops_with_bad_credentials.yml +0 -39
- data/spec/cassettes/DropService/list_drops_with_limit.yml +0 -117
- data/spec/cassettes/DropService/list_trash.yml +0 -111
- data/spec/cassettes/DropService/list_trash_with_bad_credentials.yml +0 -39
- data/spec/cassettes/DropService/retrieve_token.yml +0 -42
- data/spec/cassettes/DropService/retrieve_token_with_bad_credentials.yml +0 -43
- data/spec/cassettes/DropService/upload_file.yml +0 -291
- data/spec/cassettes/DropService/upload_public_file.yml +0 -293
- data/spec/cloudapp/config_spec.rb +0 -59
- data/spec/cloudapp/drop_content_spec.rb +0 -21
- data/spec/cloudapp/drop_presenter_spec.rb +0 -120
- data/spec/cloudapp/drop_service_spec.rb +0 -400
- data/spec/cloudapp/identity_spec.rb +0 -27
- data/spec/support/fakefs_rspec.rb +0 -5
- data/spec/support/vcr_rspec.rb +0 -9
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,30 +1,22 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cloudapp (
|
5
|
-
|
6
|
-
|
7
|
-
gli
|
8
|
-
highline
|
9
|
-
leadlight (~> 0.0.5)
|
10
|
-
typhoeus
|
4
|
+
cloudapp (2.0.0.beta.1)
|
5
|
+
leadlight (= 0.0.5)
|
6
|
+
typhoeus (~> 0.3.3)
|
11
7
|
|
12
8
|
GEM
|
13
9
|
remote: http://rubygems.org/
|
14
10
|
specs:
|
15
|
-
addressable (2.2
|
11
|
+
addressable (2.3.2)
|
16
12
|
crack (0.3.1)
|
17
13
|
diff-lcs (1.1.3)
|
18
14
|
fail-fast (1.0.0)
|
19
|
-
|
20
|
-
faraday (0.8.0.rc2)
|
15
|
+
faraday (0.8.4)
|
21
16
|
multipart-post (~> 1.1)
|
22
17
|
fattr (2.2.1)
|
23
|
-
gli (1.5.1)
|
24
|
-
highline (1.6.11)
|
25
18
|
hookr (1.1.1)
|
26
19
|
fail-fast (= 1.0.0)
|
27
|
-
hpricot (0.8.6)
|
28
20
|
leadlight (0.0.5)
|
29
21
|
addressable
|
30
22
|
faraday
|
@@ -34,29 +26,23 @@ GEM
|
|
34
26
|
mime-types
|
35
27
|
multi_json (~> 1.0.4)
|
36
28
|
link_header (0.0.5)
|
37
|
-
mime-types (1.
|
29
|
+
mime-types (1.19)
|
38
30
|
multi_json (1.0.4)
|
39
31
|
multipart-post (1.1.5)
|
40
|
-
mustache (0.99.4)
|
41
32
|
rake (0.9.2.2)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
rspec (2.
|
48
|
-
|
49
|
-
|
50
|
-
rspec-mocks (~> 2.8.0)
|
51
|
-
rspec-core (2.8.0)
|
52
|
-
rspec-expectations (2.8.0)
|
53
|
-
diff-lcs (~> 1.1.2)
|
54
|
-
rspec-mocks (2.8.0)
|
33
|
+
rspec (2.11.0)
|
34
|
+
rspec-core (~> 2.11.0)
|
35
|
+
rspec-expectations (~> 2.11.0)
|
36
|
+
rspec-mocks (~> 2.11.0)
|
37
|
+
rspec-core (2.11.1)
|
38
|
+
rspec-expectations (2.11.2)
|
39
|
+
diff-lcs (~> 1.1.3)
|
40
|
+
rspec-mocks (2.11.2)
|
55
41
|
typhoeus (0.3.3)
|
56
42
|
mime-types
|
57
|
-
vcr (2.0.
|
58
|
-
webmock (1.
|
59
|
-
addressable (
|
43
|
+
vcr (2.0.1)
|
44
|
+
webmock (1.8.9)
|
45
|
+
addressable (>= 2.2.7)
|
60
46
|
crack (>= 0.1.7)
|
61
47
|
|
62
48
|
PLATFORMS
|
@@ -64,9 +50,7 @@ PLATFORMS
|
|
64
50
|
|
65
51
|
DEPENDENCIES
|
66
52
|
cloudapp!
|
67
|
-
fakefs
|
68
53
|
rake
|
69
|
-
ronn
|
70
54
|
rspec
|
71
|
-
vcr (~> 2.0.0
|
55
|
+
vcr (~> 2.0.0)
|
72
56
|
webmock
|
data/README.md
CHANGED
@@ -26,6 +26,7 @@ goal of `cloudapp` is to be simple and Unix-friendly.
|
|
26
26
|
cloudapp list
|
27
27
|
cloudapp bookmark http://douglasadams.com
|
28
28
|
cloudapp upload ~/Desktop/screenshot.png
|
29
|
+
cloudapp download http://cl.ly/abc123
|
29
30
|
|
30
31
|
### Examples
|
31
32
|
|
@@ -36,6 +37,7 @@ goal of `cloudapp` is to be simple and Unix-friendly.
|
|
36
37
|
- List newest drops: `cloudapp list [--count=5]`
|
37
38
|
- Copy a new drop's link (OS X): `cloudapp bookmark http://douglasadams.com | pbcopy`
|
38
39
|
- Output drops in CSV: `cloudapp --format=csv list`
|
40
|
+
- Download a drop: `cloudapp download http://cl.ly/abc123`
|
39
41
|
|
40
42
|
More examples can be found on [the man page][man-page].
|
41
43
|
|
@@ -45,7 +47,6 @@ More examples can be found on [the man page][man-page].
|
|
45
47
|
|
46
48
|
`cloudapp` could be awesome with a little more flare.
|
47
49
|
|
48
|
-
- Download a drop: `cloudapp download http://cl.ly/abc123`
|
49
50
|
- Output specific columns: `cloudapp list --columns=name,views,link`
|
50
51
|
- Handle bookmarks from STDIN: `pbpaste | cloudapp bookmark`
|
51
52
|
- Handle files from STDIN: `find *.png | cloudapp upload`
|
data/Rakefile
CHANGED
@@ -48,9 +48,13 @@ require 'rspec/core/rake_task'
|
|
48
48
|
|
49
49
|
desc "Run all specs"
|
50
50
|
task RSpec::Core::RakeTask.new('spec')
|
51
|
-
|
52
51
|
task :default => "spec"
|
53
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
|
+
|
54
58
|
#############################################################################
|
55
59
|
#
|
56
60
|
# Custom tasks (add your own tasks here)
|
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 = '
|
17
|
-
s.date = '2012-
|
16
|
+
s.version = '2.0.0.beta.1'
|
17
|
+
s.date = '2012-08-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
|
-
s.executables = ["cloudapp"]
|
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,20 +43,14 @@ 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 '
|
47
|
-
s.add_dependency '
|
48
|
-
s.add_dependency 'gli'
|
49
|
-
s.add_dependency 'highline'
|
50
|
-
s.add_dependency 'leadlight', '~> 0.0.5'
|
51
|
-
s.add_dependency 'typhoeus'
|
46
|
+
s.add_dependency 'leadlight', '= 0.0.5'
|
47
|
+
s.add_dependency 'typhoeus', '~> 0.3.3'
|
52
48
|
|
53
49
|
## List your development dependencies here. Development dependencies are
|
54
50
|
## those that are only needed during development
|
55
|
-
s.add_development_dependency 'fakefs'
|
56
51
|
s.add_development_dependency 'rake'
|
57
|
-
s.add_development_dependency 'ronn'
|
58
52
|
s.add_development_dependency 'rspec'
|
59
|
-
s.add_development_dependency 'vcr', '~> 2.0.0
|
53
|
+
s.add_development_dependency 'vcr', '~> 2.0.0'
|
60
54
|
s.add_development_dependency 'webmock'
|
61
55
|
|
62
56
|
## Leave this section as-is. It will be automatically generated from the
|
@@ -70,46 +64,61 @@ Gem::Specification.new do |s|
|
|
70
64
|
MIT-LICENSE
|
71
65
|
README.md
|
72
66
|
Rakefile
|
73
|
-
bin/cloudapp
|
74
67
|
cloudapp.gemspec
|
75
68
|
lib/cloudapp.rb
|
76
|
-
lib/cloudapp/
|
69
|
+
lib/cloudapp/account.rb
|
70
|
+
lib/cloudapp/authorized_representation.rb
|
71
|
+
lib/cloudapp/collection_json.rb
|
72
|
+
lib/cloudapp/collection_json/item.rb
|
73
|
+
lib/cloudapp/collection_json/representation.rb
|
74
|
+
lib/cloudapp/collection_json/template.rb
|
75
|
+
lib/cloudapp/collection_json/tint.rb
|
77
76
|
lib/cloudapp/drop.rb
|
78
|
-
lib/cloudapp/
|
79
|
-
lib/cloudapp/
|
80
|
-
lib/cloudapp/
|
81
|
-
lib/cloudapp/identity.rb
|
77
|
+
lib/cloudapp/drop_collection.rb
|
78
|
+
lib/cloudapp/service.rb
|
79
|
+
lib/cloudapp/token.rb
|
82
80
|
man/cloudapp.1
|
83
81
|
man/cloudapp.1.html
|
84
82
|
man/cloudapp.1.ronn
|
85
|
-
spec/cassettes/
|
86
|
-
spec/cassettes/
|
87
|
-
spec/cassettes/
|
88
|
-
spec/cassettes/
|
89
|
-
spec/cassettes/
|
90
|
-
spec/cassettes/
|
91
|
-
spec/cassettes/
|
92
|
-
spec/cassettes/
|
93
|
-
spec/cassettes/
|
94
|
-
spec/cassettes/
|
95
|
-
spec/cassettes/
|
96
|
-
spec/cassettes/
|
97
|
-
spec/cassettes/
|
98
|
-
spec/cassettes/
|
99
|
-
spec/cassettes/
|
100
|
-
spec/cassettes/
|
101
|
-
spec/
|
102
|
-
spec/
|
103
|
-
spec/
|
104
|
-
spec/
|
83
|
+
spec/cassettes/create_bookmark.yml
|
84
|
+
spec/cassettes/create_bookmark_with_name.yml
|
85
|
+
spec/cassettes/create_bookmark_with_privacy.yml
|
86
|
+
spec/cassettes/delete_drop.yml
|
87
|
+
spec/cassettes/list_drops.yml
|
88
|
+
spec/cassettes/list_drops_with_bad_token.yml
|
89
|
+
spec/cassettes/list_drops_with_filter.yml
|
90
|
+
spec/cassettes/list_drops_with_href.yml
|
91
|
+
spec/cassettes/list_drops_with_href_and_filter.yml
|
92
|
+
spec/cassettes/list_drops_with_href_and_limit.yml
|
93
|
+
spec/cassettes/list_drops_with_limit.yml
|
94
|
+
spec/cassettes/list_drops_with_nil_href.yml
|
95
|
+
spec/cassettes/purge_drops.yml
|
96
|
+
spec/cassettes/recover_drop.yml
|
97
|
+
spec/cassettes/rename_drop.yml
|
98
|
+
spec/cassettes/setup_drops.yml
|
99
|
+
spec/cassettes/token_for_account.yml
|
100
|
+
spec/cassettes/token_for_account_with_bad_credentials.yml
|
101
|
+
spec/cassettes/trash_drop.yml
|
102
|
+
spec/cassettes/update_drop_bookmark_url.yml
|
103
|
+
spec/cassettes/update_file.yml
|
104
|
+
spec/cassettes/upload_file.yml
|
105
|
+
spec/cassettes/upload_file_with_name.yml
|
106
|
+
spec/cassettes/upload_file_with_privacy.yml
|
107
|
+
spec/cassettes/view_drop.yml
|
108
|
+
spec/cloudapp/account_spec.rb
|
109
|
+
spec/cloudapp/authorized_representation_spec.rb
|
110
|
+
spec/cloudapp/collection_json/item_spec.rb
|
111
|
+
spec/cloudapp/collection_json/representation_spec.rb
|
112
|
+
spec/cloudapp/collection_json/template_spec.rb
|
113
|
+
spec/cloudapp/drop_collection_spec.rb
|
105
114
|
spec/cloudapp/drop_spec.rb
|
106
|
-
spec/cloudapp/
|
115
|
+
spec/cloudapp/service_spec.rb
|
116
|
+
spec/cloudapp/token_spec.rb
|
107
117
|
spec/helper.rb
|
108
|
-
spec/
|
118
|
+
spec/integration_spec.rb
|
109
119
|
spec/support/files/favicon.ico
|
110
120
|
spec/support/stub_class_or_module.rb
|
111
121
|
spec/support/vcr.rb
|
112
|
-
spec/support/vcr_rspec.rb
|
113
122
|
]
|
114
123
|
# = MANIFEST =
|
115
124
|
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'cloudapp/drop'
|
3
|
+
require 'cloudapp/drop_collection'
|
4
|
+
|
5
|
+
# Usage:
|
6
|
+
#
|
7
|
+
# # Create a new service passing CloudApp account token:
|
8
|
+
# account = CloudApp::Account.using_token token
|
9
|
+
#
|
10
|
+
# # Newest drops
|
11
|
+
# account.drops #=> Active drops
|
12
|
+
# account.drops filter: :active #=> Active drops
|
13
|
+
# account.drops filter: :trash #=> Trashed drops
|
14
|
+
# account.drops filter: :all #=> All active and trashed drops
|
15
|
+
#
|
16
|
+
# # List specific page of drops:
|
17
|
+
# page1 = account.drops
|
18
|
+
# page2 = account.drops href: page1.link('next') # Advance to page 2
|
19
|
+
# page1 = account.drops href: page2.link('previous') # Go back to page 1
|
20
|
+
#
|
21
|
+
# # Newest 5 drops
|
22
|
+
# account.drops limit: 5
|
23
|
+
#
|
24
|
+
# # View specific drop:
|
25
|
+
# account.drop_at drop.href
|
26
|
+
#
|
27
|
+
# # Create a bookmark:
|
28
|
+
# account.bookmark 'http://getcloudapp.com'
|
29
|
+
# account.bookmark 'http://getcloudapp.com', name: 'CloudApp'
|
30
|
+
# account.bookmark 'http://getcloudapp.com', private: false
|
31
|
+
#
|
32
|
+
# # Upload a file:
|
33
|
+
# account.upload #<Pathname>
|
34
|
+
# account.upload #<Pathname>, name: 'Screen shot'
|
35
|
+
# account.upload #<Pathname>, private: false
|
36
|
+
#
|
37
|
+
# # Update a drop:
|
38
|
+
# account.update drop.href, name: 'CloudApp'
|
39
|
+
# account.update drop.href, private: false
|
40
|
+
#
|
41
|
+
# # Trash a drop:
|
42
|
+
# account.trash_drop 42
|
43
|
+
#
|
44
|
+
# # Recover a drop from the trash:
|
45
|
+
# account.recover_drop 42
|
46
|
+
#
|
47
|
+
# # Delete a drop:
|
48
|
+
# account.delete_drop 42
|
49
|
+
#
|
50
|
+
module CloudApp
|
51
|
+
class Account
|
52
|
+
extend Forwardable
|
53
|
+
def_delegators :service, :delete_drop
|
54
|
+
|
55
|
+
class << self
|
56
|
+
attr_writer :service_source
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.service_source
|
60
|
+
@service_source ||= CloudApp::Service.public_method(:new)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.service
|
64
|
+
service_source.call
|
65
|
+
end
|
66
|
+
|
67
|
+
def initialize(token = nil)
|
68
|
+
@token = token
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.using_token(token)
|
72
|
+
CloudApp::Account.new token
|
73
|
+
end
|
74
|
+
|
75
|
+
def drops(*args)
|
76
|
+
DropCollection.new service.drops(*args)
|
77
|
+
end
|
78
|
+
|
79
|
+
def drop_at(*args)
|
80
|
+
DropCollection.new service.drop_at(*args)
|
81
|
+
end
|
82
|
+
|
83
|
+
def bookmark(*args)
|
84
|
+
DropCollection.new service.bookmark(*args)
|
85
|
+
end
|
86
|
+
|
87
|
+
def upload(*args)
|
88
|
+
DropCollection.new service.upload(*args)
|
89
|
+
end
|
90
|
+
|
91
|
+
def update(*args)
|
92
|
+
DropCollection.new service.update(*args)
|
93
|
+
end
|
94
|
+
|
95
|
+
def trash_drop(*args)
|
96
|
+
DropCollection.new service.trash_drop(*args)
|
97
|
+
end
|
98
|
+
|
99
|
+
def recover_drop(*args)
|
100
|
+
DropCollection.new service.recover_drop(*args)
|
101
|
+
end
|
102
|
+
|
103
|
+
protected
|
104
|
+
|
105
|
+
def service
|
106
|
+
@service ||= self.class.service.tap do |service|
|
107
|
+
service.token = @token if @token
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'leadlight'
|
2
|
+
|
3
|
+
module CloudApp
|
4
|
+
module AuthorizedRepresentation
|
5
|
+
Tint = Leadlight::Tint.new 'authorized', status: [ :success, 401 ] do
|
6
|
+
extend AuthorizedRepresentation
|
7
|
+
end
|
8
|
+
|
9
|
+
def authorized?
|
10
|
+
not unauthorized?
|
11
|
+
end
|
12
|
+
|
13
|
+
def unauthorized?
|
14
|
+
__response__.status == 401
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module CloudApp
|
4
|
+
module CollectionJson
|
5
|
+
class Item
|
6
|
+
attr_reader :href, :links, :data
|
7
|
+
def initialize(item_data)
|
8
|
+
@href = item_data.fetch('href', nil)
|
9
|
+
@links = item_data.fetch('links', []).map {|link| OpenStruct.new(link) }
|
10
|
+
@data = DataCollection.hash_from(item_data.fetch('data'))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
class DataCollection
|
15
|
+
def self.hash_from(data)
|
16
|
+
Hash[data.map {|datum| [ datum['name'], datum['value'] ]}]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
|
3
|
+
module CloudApp
|
4
|
+
module CollectionJson
|
5
|
+
module Representation
|
6
|
+
def href
|
7
|
+
collection.fetch('href')
|
8
|
+
end
|
9
|
+
|
10
|
+
def collection_links
|
11
|
+
return [] unless collection.has_key?('links')
|
12
|
+
collection.fetch('links').map {|link| OpenStruct.new(link) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def items(item_source = default_item_source)
|
16
|
+
collection.fetch('items').map {|item|
|
17
|
+
item_source.call(item)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Ultimately this API would be nice:
|
22
|
+
#
|
23
|
+
# root.template(email: email, password: password).
|
24
|
+
# post do |response|
|
25
|
+
# return response
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# The Command Pattern could be nice as well. Template#[] may be a better
|
29
|
+
# solution than faux methods.
|
30
|
+
#
|
31
|
+
# root.create do |template|
|
32
|
+
# template.email = email
|
33
|
+
# template.password = password
|
34
|
+
# end
|
35
|
+
#
|
36
|
+
# Updates also use the template.
|
37
|
+
#
|
38
|
+
# root.items.first.update do |template|
|
39
|
+
# template.name.reverse!
|
40
|
+
# end
|
41
|
+
def template(template_source = default_template_source)
|
42
|
+
return unless collection.has_key?('template')
|
43
|
+
template_source.call collection.fetch('template')
|
44
|
+
end
|
45
|
+
|
46
|
+
def queries(query_source = default_query_source)
|
47
|
+
return unless collection.has_key?('queries')
|
48
|
+
collection.fetch('queries').map {|query| query_source.call(query) }
|
49
|
+
end
|
50
|
+
|
51
|
+
def query(rel, query_source = default_query_source)
|
52
|
+
Array(queries(query_source)).find {|query| query.rel == rel }
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
def default_item_source
|
58
|
+
CloudApp::CollectionJson::Item.public_method(:new)
|
59
|
+
end
|
60
|
+
|
61
|
+
def default_template_source
|
62
|
+
CloudApp::CollectionJson::Template.public_method(:new)
|
63
|
+
end
|
64
|
+
|
65
|
+
def default_query_source
|
66
|
+
CloudApp::CollectionJson::Template.public_method(:new)
|
67
|
+
end
|
68
|
+
|
69
|
+
def collection
|
70
|
+
self.fetch('collection')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module CloudApp
|
2
|
+
module CollectionJson
|
3
|
+
class Template < Item
|
4
|
+
attr_reader :rel, :enctype
|
5
|
+
def initialize(template_data)
|
6
|
+
super
|
7
|
+
@rel = template_data.fetch('rel', nil)
|
8
|
+
@enctype = template_data.fetch('enctype', nil)
|
9
|
+
end
|
10
|
+
|
11
|
+
def fill(template_data)
|
12
|
+
template_data = template_data.select {|key| data.has_key?(key) }
|
13
|
+
data.merge template_data
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,11 @@
|
|
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 CollectionJson::Representation
|
6
|
+
collection_links.each do |link|
|
7
|
+
add_link link.href, link.rel
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/lib/cloudapp/drop.rb
CHANGED
@@ -1,16 +1,32 @@
|
|
1
|
+
require 'date'
|
1
2
|
require 'ostruct'
|
2
3
|
|
3
4
|
module CloudApp
|
4
5
|
class Drop < OpenStruct
|
5
|
-
|
6
|
-
def public? () !private? end
|
6
|
+
attr_accessor :href, :data
|
7
7
|
|
8
|
-
def
|
9
|
-
|
8
|
+
def initialize(collection_item)
|
9
|
+
@href = collection_item.href
|
10
|
+
@links = collection_item.links
|
11
|
+
@data = collection_item.data
|
12
|
+
super @data
|
10
13
|
end
|
11
14
|
|
12
|
-
def
|
13
|
-
|
15
|
+
def name() super || share_url end
|
16
|
+
def private?() private == true end
|
17
|
+
def public?() !private? end
|
18
|
+
def created() DateTime.parse(super) end
|
19
|
+
|
20
|
+
def share_url() link_for_relation('canonical') end
|
21
|
+
def thumbnail_url() link_for_relation('icon') end
|
22
|
+
def embed_url() link_for_relation('embed') end
|
23
|
+
def download_url() link_for_relation('download') end
|
24
|
+
|
25
|
+
protected
|
26
|
+
|
27
|
+
def link_for_relation(relation)
|
28
|
+
link = @links.find {|link| link.rel == relation }
|
29
|
+
link and link.href
|
14
30
|
end
|
15
31
|
end
|
16
32
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'delegate'
|
2
|
+
require 'forwardable'
|
3
|
+
|
4
|
+
module CloudApp
|
5
|
+
class DropCollection < SimpleDelegator
|
6
|
+
extend Forwardable
|
7
|
+
def_delegators :@representation, :authorized?, :unauthorized?, :link, :links
|
8
|
+
|
9
|
+
def initialize(representation, drop_class = Drop)
|
10
|
+
@representation = representation
|
11
|
+
@drop_class = drop_class
|
12
|
+
super drops
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def drops
|
18
|
+
return [] if unauthorized?
|
19
|
+
@drops ||= @representation.items.map {|drop| @drop_class.new(drop) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|