bucket_client 0.1.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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.gitlab-ci.yml +70 -0
  4. data/.idea/bucket_client.iml +105 -0
  5. data/.idea/encodings.xml +4 -0
  6. data/.idea/misc.xml +7 -0
  7. data/.idea/modules.xml +8 -0
  8. data/.idea/runConfigurations/Integration_Test.xml +37 -0
  9. data/.idea/runConfigurations/Unit_Test.xml +37 -0
  10. data/.rspec +3 -0
  11. data/CODE_OF_CONDUCT.md +74 -0
  12. data/Gemfile +6 -0
  13. data/Gemfile.lock +114 -0
  14. data/LICENSE.txt +21 -0
  15. data/README.md +870 -0
  16. data/Rakefile +6 -0
  17. data/bin/console +14 -0
  18. data/bin/setup +8 -0
  19. data/bucket_client.gemspec +46 -0
  20. data/integration/aws_blob_spec.rb +134 -0
  21. data/integration/aws_bucket_spec.rb +145 -0
  22. data/integration/azure_blob_spec.rb +132 -0
  23. data/integration/azure_bucket_spec.rb +132 -0
  24. data/integration/dev_blob_spec.rb +131 -0
  25. data/integration/dev_bucket_spec.rb +140 -0
  26. data/integration/do_blob_spec.rb +134 -0
  27. data/integration/do_bucket_spec.rb +144 -0
  28. data/integration/gcp_blob_spec.rb +132 -0
  29. data/integration/gcp_bucket_spec.rb +132 -0
  30. data/integration/img.jpg +0 -0
  31. data/lib/bucket_client.rb +66 -0
  32. data/lib/bucket_client/aws/aws_bucket.rb +85 -0
  33. data/lib/bucket_client/aws/aws_client.rb +195 -0
  34. data/lib/bucket_client/aws/aws_http_client.rb +32 -0
  35. data/lib/bucket_client/aws/aws_policy_factory.rb +26 -0
  36. data/lib/bucket_client/aws4_request_signer.rb +133 -0
  37. data/lib/bucket_client/azure/azure_bucket.rb +83 -0
  38. data/lib/bucket_client/azure/azure_client.rb +197 -0
  39. data/lib/bucket_client/bucket.rb +388 -0
  40. data/lib/bucket_client/bucket_operation_exception.rb +8 -0
  41. data/lib/bucket_client/client.rb +408 -0
  42. data/lib/bucket_client/dev/local_bucket.rb +84 -0
  43. data/lib/bucket_client/dev/local_client.rb +148 -0
  44. data/lib/bucket_client/digital_ocean/digital_ocean_acl_factory.rb +39 -0
  45. data/lib/bucket_client/digital_ocean/digital_ocean_bucket.rb +81 -0
  46. data/lib/bucket_client/digital_ocean/digital_ocean_client.rb +275 -0
  47. data/lib/bucket_client/digital_ocean/digital_ocean_http_client.rb +31 -0
  48. data/lib/bucket_client/gcp/gcp_bucket.rb +79 -0
  49. data/lib/bucket_client/gcp/gcp_client.rb +171 -0
  50. data/lib/bucket_client/operation_result.rb +33 -0
  51. data/lib/bucket_client/version.rb +3 -0
  52. metadata +246 -0
@@ -0,0 +1,31 @@
1
+ module BucketClient
2
+ class DigitalOceanHttpClient
3
+ # @param [Client::AWS4RequestSigner] signer aws4 signer
4
+ # @param [String] region region of the service
5
+ # @param [KirinHttp::Client] http Http client to send http Message
6
+ def initialize(signer, region, http)
7
+ @signer = signer
8
+ @region = region
9
+ @http = http
10
+ end
11
+
12
+ # @param [Symbol] method
13
+ # @param [String] endpoint
14
+ # @param [Object] content
15
+ # @param [String] type
16
+ # @param [String] accept
17
+ # @param [Hash] headers
18
+ # @return [KirinHttp::Response]
19
+ def query(method, endpoint, content = nil, type = "application/xml", accept = nil, headers = {})
20
+ accept = type if accept.nil?
21
+ header = {
22
+ "Content-Type": type,
23
+ "Accept": accept
24
+ }.merge(headers)
25
+ message = KirinHttp::Message.new(endpoint, method, content, header)
26
+ message = @signer.sign message, "s3", @region
27
+ @http.send message
28
+ end
29
+ end
30
+ end
31
+
@@ -0,0 +1,79 @@
1
+ module BucketClient
2
+ class GCPBucket < Bucket
3
+ attr_reader :key
4
+
5
+ # @param [GCPClient] parent
6
+ # @param [String] key
7
+ def initialize(parent, key)
8
+ @bucket_client = parent
9
+ @key = key
10
+ end
11
+
12
+ def get_uri(key)
13
+ "https://storage.googleapis.com/#{@key}/#{key}"
14
+ end
15
+
16
+ def get_blob_with_uri(uri)
17
+ @bucket_client.get_blob uri
18
+ end
19
+
20
+ def exist_blob_with_uri(uri)
21
+ @bucket_client.exist_blob(uri)
22
+ end
23
+
24
+ def put_blob_with_uri(payload, uri)
25
+ @bucket_client.put_blob payload, uri
26
+ end
27
+
28
+ def update_blob_with_uri(payload, uri)
29
+ exist = exist_blob_with_uri uri
30
+ if exist
31
+ put_blob_with_uri payload, uri
32
+ else
33
+ OperationResult.new false, "Blob does not exist", nil, 400
34
+ end
35
+ end
36
+
37
+ def delete_blob_with_uri(uri)
38
+ @bucket_client.delete_blob(uri)
39
+ end
40
+
41
+ def delete_blob_if_exist_with_uri(uri)
42
+ @bucket_client.delete_blob_if_exist(uri)
43
+ end
44
+
45
+ def get_blob(key)
46
+ get_blob_with_uri(get_uri key)
47
+ end
48
+
49
+ def exist_blob(key)
50
+ exist_blob_with_uri(get_uri key)
51
+ end
52
+
53
+ def put_blob(payload, key)
54
+ put_blob_with_uri(payload, get_uri(key))
55
+ end
56
+
57
+ def create_blob(payload, key)
58
+ exist = exist_blob key
59
+ if exist
60
+ OperationResult.new false, "Blob already exist", nil, 400
61
+ else
62
+ put_blob payload, key
63
+ end
64
+ end
65
+
66
+ def update_blob(payload, key)
67
+ update_blob_with_uri(payload, get_uri(key))
68
+ end
69
+
70
+ def delete_blob(key)
71
+ delete_blob_with_uri(get_uri key)
72
+ end
73
+
74
+ def delete_blob_if_exist(key)
75
+ delete_blob_if_exist_with_uri(get_uri key)
76
+ end
77
+
78
+ end
79
+ end
@@ -0,0 +1,171 @@
1
+ require "google/cloud/storage"
2
+ require "mimemagic"
3
+ require "bucket_client/operation_result"
4
+ require "bucket_client/gcp/gcp_bucket"
5
+
6
+ module BucketClient
7
+ class GCPClient < Client
8
+ def initialize(project_id, secret)
9
+ @client = Google::Cloud::Storage.new(project_id: project_id, keyfile: secret)
10
+ end
11
+
12
+ def exist_bucket(key)
13
+ !@client.bucket(key).nil?
14
+ end
15
+
16
+ def get_bucket!(key)
17
+ GCPBucket.new(self, key)
18
+ end
19
+
20
+ def put_bucket(key)
21
+ exist = exist_bucket key
22
+ if exist
23
+ bucket = get_bucket! key
24
+ OperationResult.new(true, "OK", bucket, 200)
25
+ else
26
+ create_bucket key
27
+ end
28
+ end
29
+
30
+ def create_bucket(key)
31
+ begin
32
+ @client.create_bucket key
33
+ bucket = get_bucket! key
34
+ OperationResult.new(true, "OK", bucket, 200)
35
+ rescue StandardError => e
36
+ OperationResult.new(false, e.message, nil, 400)
37
+ end
38
+ end
39
+
40
+ def delete_bucket(key)
41
+ exist = exist_bucket key
42
+ if exist
43
+ bucket = @client.bucket(key)
44
+ success = bucket.delete
45
+ message = success ? "Deleted" : "Failed to delete"
46
+ code = success ? 204 : 400
47
+ OperationResult.new(success, message, nil, code)
48
+ else
49
+ OperationResult.new(false, "Bucket does not exist", nil, 404)
50
+ end
51
+ end
52
+
53
+ def delete_bucket_if_exist(key)
54
+ exist = exist_bucket key
55
+ if exist
56
+ delete_bucket key
57
+ else
58
+ OperationResult.new(true, "Bucket already deleted", nil, 200)
59
+ end
60
+ end
61
+
62
+ def set_read_policy(key, access)
63
+ raise ArgumentError.new("Read Policy not accepted") if access != :public && access != :private
64
+ begin
65
+ bucket = @client.bucket key
66
+ modify_acl bucket, access
67
+ bucket.files.each do |file|
68
+ modify_acl file, access
69
+ end
70
+ OperationResult.new(true, "OK", nil, 200)
71
+ rescue StandardError => e
72
+ OperationResult.new(false, e.message, nil, 400)
73
+ end
74
+ end
75
+
76
+ def set_get_cors(key, cors)
77
+ begin
78
+
79
+ bucket = @client.bucket key
80
+ bucket.cors(&:clear)
81
+ bucket.cors {|rules| rules.add_rule cors, "GET"}
82
+ OperationResult.new(true, "OK", nil, 200)
83
+ rescue StandardError => e
84
+ OperationResult.new(false, e.message, nil, 400)
85
+ end
86
+ end
87
+
88
+ def get_blob(uri)
89
+ data = break_uri uri
90
+ begin
91
+ bucket = @client.bucket data[:bucket]
92
+ blob = bucket.file data[:blob]
93
+ bin = blob.download.read
94
+ OperationResult.new(true, "OK", bin, 200)
95
+ rescue StandardError => e
96
+ OperationResult.new(false, e.message, nil, 400)
97
+ end
98
+ end
99
+
100
+ def exist_blob(uri)
101
+ data = break_uri uri
102
+ bucket = @client.bucket data[:bucket]
103
+ bucket.file(data[:blob], skip_lookup: true).exists?
104
+ end
105
+
106
+ def put_blob(payload, uri)
107
+ mime = MimeMagic.by_magic payload
108
+ data = break_uri uri
109
+ begin
110
+ # @type [Google::Cloud::Storage::Bucket]
111
+ bucket = @client.bucket data[:bucket]
112
+ f = StringIO.new
113
+ f << payload
114
+ file = bucket.create_file f, data[:blob], cache_control: "no-cache", content_type: mime.type
115
+ OperationResult.new(true, "OK", file.public_url, 200)
116
+ rescue StandardError => e
117
+ OperationResult.new(false, e.message, nil, 400)
118
+ end
119
+ end
120
+
121
+ def update_blob(payload, uri)
122
+ exist = exist_blob uri
123
+ if exist
124
+ put_blob payload, uri
125
+ else
126
+ OperationResult.new(false, "Blob does not exist", nil, 404)
127
+ end
128
+ end
129
+
130
+ def delete_blob_if_exist(uri)
131
+ exist = exist_blob uri
132
+ if exist
133
+ delete_blob uri
134
+ else
135
+ OperationResult.new(true, "Blob already deleted", nil, 204)
136
+ end
137
+ end
138
+
139
+ def delete_blob(uri)
140
+ data = break_uri uri
141
+ begin
142
+ bucket = @client.bucket data[:bucket]
143
+ bucket.file(data[:blob], skip_lookup: true).delete
144
+ OperationResult.new(true, "Deleted Blob", nil, 204)
145
+ rescue StandardError => e
146
+ OperationResult.new(false, e.message, nil, 400)
147
+ end
148
+ end
149
+
150
+ private
151
+
152
+ def break_uri(uri)
153
+ url = Addressable::URI.parse uri
154
+ fragments = url.path.split("/").select {|x| !x.nil? && !x.empty?}
155
+ bucket = fragments[0]
156
+ blob = fragments.drop(1).join "/"
157
+ {bucket: bucket, blob: blob}
158
+ end
159
+
160
+ def modify_acl(principal, access)
161
+ if access == :private
162
+ principal.acl.private!
163
+ principal.default_acl.private!
164
+ else
165
+ principal.acl.public!
166
+ principal.default_acl.public!
167
+ end
168
+ end
169
+
170
+ end
171
+ end
@@ -0,0 +1,33 @@
1
+ class OperationResult
2
+
3
+ def initialize(success, message, value, code)
4
+ @success = success
5
+ @message = message
6
+ @value = value
7
+ @code = code
8
+ end
9
+
10
+ # Message from the server of the operation. Failure message will be here too
11
+ # @return [String]
12
+ def message
13
+ @message
14
+ end
15
+
16
+ # HTTP Status code of the operation.
17
+ # @return [Integer]
18
+ def code
19
+ @code
20
+ end
21
+
22
+ # Whether the operation was successful
23
+ # @return [Boolean]
24
+ def success
25
+ @success
26
+ end
27
+
28
+ # Value of the operation result if it has a value.
29
+ # Can be uri or byte array
30
+ def value
31
+ @value
32
+ end
33
+ end
@@ -0,0 +1,3 @@
1
+ module BucketClient
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,246 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bucket_client
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - kirinnee
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2019-03-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: kirin_http
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: mimemagic
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: ox
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: azure-storage-blob
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: addressable
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '2.5'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '2.5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: google-cloud-storage
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '1.17'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '1.17'
97
+ - !ruby/object:Gem::Dependency
98
+ name: bundler
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.17'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.17'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '10.0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '10.0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '3.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '3.0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: dotenv
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ description: |-
154
+ Bucket Client is a ruby gem that allows programmers to interact with popular Blob Storage cloud
155
+ services. This intends to act as a layer of abstraction, much like ORM is to databases.
156
+
157
+ With this, you may easily change the blob storage provider or even defer them.
158
+
159
+ The supported cloud storage include:
160
+ - Google Cloud Platform Cloud Storage
161
+ - Amazon Web Service S3 Bucket
162
+ - Digital Ocean Spaces
163
+ - Azure Blob Storage (Microsoft).
164
+ email:
165
+ - kirinnee97@gmail.com
166
+ executables: []
167
+ extensions: []
168
+ extra_rdoc_files: []
169
+ files:
170
+ - ".env"
171
+ - ".gitignore"
172
+ - ".gitlab-ci.yml"
173
+ - ".idea/bucket_client.iml"
174
+ - ".idea/encodings.xml"
175
+ - ".idea/misc.xml"
176
+ - ".idea/modules.xml"
177
+ - ".idea/runConfigurations/Integration_Test.xml"
178
+ - ".idea/runConfigurations/Unit_Test.xml"
179
+ - ".idea/vcs.xml"
180
+ - ".rspec"
181
+ - CODE_OF_CONDUCT.md
182
+ - Gemfile
183
+ - Gemfile.lock
184
+ - LICENSE.txt
185
+ - README.md
186
+ - Rakefile
187
+ - bin/console
188
+ - bin/setup
189
+ - bucket_client.gemspec
190
+ - integration/aws_blob_spec.rb
191
+ - integration/aws_bucket_spec.rb
192
+ - integration/azure_blob_spec.rb
193
+ - integration/azure_bucket_spec.rb
194
+ - integration/dev_blob_spec.rb
195
+ - integration/dev_bucket_spec.rb
196
+ - integration/do_blob_spec.rb
197
+ - integration/do_bucket_spec.rb
198
+ - integration/gcp_blob_spec.rb
199
+ - integration/gcp_bucket_spec.rb
200
+ - integration/img.jpg
201
+ - lib/bucket_client.rb
202
+ - lib/bucket_client/aws/aws_bucket.rb
203
+ - lib/bucket_client/aws/aws_client.rb
204
+ - lib/bucket_client/aws/aws_http_client.rb
205
+ - lib/bucket_client/aws/aws_policy_factory.rb
206
+ - lib/bucket_client/aws4_request_signer.rb
207
+ - lib/bucket_client/azure/azure_bucket.rb
208
+ - lib/bucket_client/azure/azure_client.rb
209
+ - lib/bucket_client/bucket.rb
210
+ - lib/bucket_client/bucket_operation_exception.rb
211
+ - lib/bucket_client/client.rb
212
+ - lib/bucket_client/dev/local_bucket.rb
213
+ - lib/bucket_client/dev/local_client.rb
214
+ - lib/bucket_client/digital_ocean/digital_ocean_acl_factory.rb
215
+ - lib/bucket_client/digital_ocean/digital_ocean_bucket.rb
216
+ - lib/bucket_client/digital_ocean/digital_ocean_client.rb
217
+ - lib/bucket_client/digital_ocean/digital_ocean_http_client.rb
218
+ - lib/bucket_client/gcp/gcp_bucket.rb
219
+ - lib/bucket_client/gcp/gcp_client.rb
220
+ - lib/bucket_client/operation_result.rb
221
+ - lib/bucket_client/version.rb
222
+ homepage: https://gitlab.com/ruby-gem/bucket_client
223
+ licenses:
224
+ - MIT
225
+ metadata: {}
226
+ post_install_message:
227
+ rdoc_options: []
228
+ require_paths:
229
+ - lib
230
+ required_ruby_version: !ruby/object:Gem::Requirement
231
+ requirements:
232
+ - - ">="
233
+ - !ruby/object:Gem::Version
234
+ version: '0'
235
+ required_rubygems_version: !ruby/object:Gem::Requirement
236
+ requirements:
237
+ - - ">="
238
+ - !ruby/object:Gem::Version
239
+ version: '0'
240
+ requirements: []
241
+ rubygems_version: 3.0.1
242
+ signing_key:
243
+ specification_version: 4
244
+ summary: A gem that allows for ruby code to interact with cloud blob storage such
245
+ as AWS S3, GCP Cloud Storage and Azure Blob Storage
246
+ test_files: []