bkblz 0.1.2 → 0.1.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5e5b80d7bec5fcf808b83fea5b07e508dc215e84
4
- data.tar.gz: 50eba053e7feb3bf6ab847519ecac06d6a224d3a
3
+ metadata.gz: 4c2440a3e12c3022fbc44a05079430bc77c80a56
4
+ data.tar.gz: 667e2e0a9a71e6ceaf81aec43eca2f6e1f9c2d51
5
5
  SHA512:
6
- metadata.gz: 586eb75671ece61435dd0bbfa3f28ff01e18b74286e9549dd9692dc7409c7e26e49ee51bbab579e7a75a94dc268abc04871f1322af4af77426bf854af5c1316c
7
- data.tar.gz: 7d992fc8b24164ad07da989f0c5cf36c9c8beba3135f339b7ea9833cfe13674039a4d57bbf136a9135ff5a69147195e2bad400202b0285cf388dd85912032f41
6
+ metadata.gz: 0b2c6b5912e130d96ffab0390e098fd0b35e197f30240a856b21fca701cbe56396d7ecd5bb04fd9e5587725c430322e5f04e867acee8e578a02bcd5a9aae0652
7
+ data.tar.gz: ea2b13a18d20c29bb5929969137dede83e20782f5ecbe38b791d16c3ea0205576f9b2c5ee53b5fcfb92036a4f11a5f015cbeb3632389db59cf2da740dd189aaf
data/README.rb CHANGED
@@ -1,8 +1,28 @@
1
- # Run `ruby README.rb` for a working demo, but first add your
2
- # application key and account id in the slots below.
1
+ =begin
3
2
 
4
- # Or `gem install bkblz` to begin. After install try `bkblz -h` to use
5
- # the CLI
3
+ This is the bkblz ruby gem, a library for the Backblaze B2 cloud
4
+ storage API: https://www.backblaze.com/b2/docs/
5
+
6
+ Currently the gem supports the following V1 API calls:
7
+
8
+ * b2_authorize_account
9
+ * b2_create_bucket
10
+ * b2_delete_bucket
11
+ * b2_delete_file_version
12
+ * b2_list_buckets
13
+ * b2_list_file_names
14
+ * b2_list_file_versions
15
+ * b2_upload_file
16
+ * b2_download_file_by_id
17
+ * b2_download_file_by_name
18
+
19
+ Run `ruby README.rb` for a working demo, but first add your
20
+ application key and account id in the slots below.
21
+
22
+ Or `gem install bkblz` to begin. After install try `bkblz -h` to use
23
+ the CLI
24
+
25
+ =end
6
26
 
7
27
  $: << 'lib'
8
28
  require 'bkblz'
@@ -29,109 +49,157 @@ if Bkblz.config.account_id.match /!!!/
29
49
  exit 1
30
50
  end
31
51
 
32
- Bkblz.log.info do <<-EOS
33
- # Using the config above, create an authorized session. All
34
- # requests will run in the context of this session. See
35
- # +Bkblz::V1::Session#authorize+.
36
- EOS
37
- end
38
- Bkblz::V1::Session.authorize Bkblz.config do |api_session|
39
- Bkblz.log.info "API session => #{api_session}"
40
-
41
- Bkblz.log.info do <<-EOS
42
- # First try to find an existing bucket named my-test-bucket,
43
- # we'll use that if it exists. All requests in a session are sent
44
- # through the session so that the request object gets access to the
45
- # auth credentials.
46
- EOS
47
- end
48
- buckets = api_session.send(Bkblz::V1::ListBucketsRequest.new).buckets
49
- bucket = buckets.select { |b| b.bucket_name == "my-test-bucket" }.first
50
- Bkblz.log.info "bucket list => #{buckets}"
51
-
52
+ def run_readme
52
53
  Bkblz.log.info do <<-EOS
53
- # Otherwise create a new my-test-bucket
54
+ # Using the config above, create an authorized session. All
55
+ # requests will run in the context of this session. See
56
+ # +Bkblz::V1::Session#authorize+.
54
57
  EOS
55
58
  end
56
- unless bucket
57
- bucket = Bkblz::V1::Model::Bucket.new \
58
- :bucket_name => "my-test-bucket",
59
- :bucket_type => "allPrivate",
60
- :account_id => api_session.account_id
59
+ Bkblz::V1::Session.authorize Bkblz.config do |session|
60
+ Bkblz.log.info "API session => #{session}"
61
61
 
62
62
  Bkblz.log.info do <<-EOS
63
- # Pass a model to the CreateBucketRequest,
64
- # models are just named wrappers with dynamic methods
65
- # around the JSON responses provided back from the Bkblz
66
- # API. See lib/bkblz/v1/models.rb for a list of defined API
67
- # objects. See Bkblz::V1::Model::Base for how it work.
63
+ # First try to find an existing bucket named my-test-bucket,
64
+ # we'll use that if it exists. All requests in a session are sent
65
+ # through the session so that the request object gets access to the
66
+ # auth credentials.
68
67
  EOS
69
68
  end
70
- request = Bkblz::V1::CreateBucketRequest.new bucket
71
- Bkblz.log.info "bucket model => #{bucket}"
72
-
73
- # Bkblz::V1::Response objects are returned from +send+. Some
74
- # provide a to_model method if they declare the +response_model+
75
- # in the class definition.
76
- bucket = api_session.send(request).to_model
77
- Bkblz.log.info "created bucket => #{bucket.bucket_name}/#{bucket.bucket_id}"
78
- end
79
-
80
- Bkblz.log.info do <<-EOS
81
- # Uploading a file begins with getting a dynamic URL from the API.
82
- EOS
83
- end
84
- upload_auth = api_session.send(
85
- Bkblz::V1::GetUploadUrlRequest.new bucket.bucket_id).to_model
86
- Bkblz.log.info "upload file URL => #{upload_auth.upload_url}"
69
+ buckets = session.send(Bkblz::V1::ListBucketsRequest.new).buckets
70
+ Bkblz.log.info "bucket list => #{buckets}"
87
71
 
72
+ new_bucket_name = "bkblz-readme-bucket"
73
+ bucket = buckets.find { |b| b.bucket_name == new_bucket_name }
88
74
 
89
- Bkblz.log.info do <<-EOS
90
- # Use the upload_auth model (a
91
- # Bkblz::V1::Model::UploadAuth) to upload some files.
92
- EOS
93
- end
94
- 5.times do |i|
95
- body = "some text #{i}"
96
- file_name = "some_text_#{i}.txt"
97
- content_type = nil
75
+ Bkblz.log.info do <<-EOS
76
+ # Otherwise create a new my-test-bucket
77
+ EOS
78
+ end
98
79
 
99
- upload_file_info = api_session.send(
100
- Bkblz::V1::UploadFileRequest.new upload_auth, body, file_name,
80
+ begin
81
+ unless bucket
82
+ bucket = Bkblz::V1::Model::Bucket.new \
83
+ :bucket_name => new_bucket_name,
84
+ :bucket_type => "allPrivate",
85
+ :account_id => session.account_id
86
+
87
+ Bkblz.log.info do <<-EOS
88
+ # Pass a model to the CreateBucketRequest,
89
+ # models are just named wrappers with dynamic methods
90
+ # around the JSON responses provided back from the Bkblz
91
+ # API. See lib/bkblz/v1/models.rb for a list of defined API
92
+ # objects. See Bkblz::V1::Model::Base for how it work.
93
+ EOS
94
+ end
95
+ request = Bkblz::V1::CreateBucketRequest.new bucket
96
+ Bkblz.log.info "bucket model => #{bucket}"
97
+
98
+ # Bkblz::V1::Response objects are returned from +send+. Some
99
+ # provide a to_model method if they declare the +response_model+
100
+ # in the class definition.
101
+ bucket = session.send(request).to_model
102
+ Bkblz.log.info "created bucket => #{bucket}"
103
+ end
104
+
105
+ Bkblz.log.info do <<-EOS
106
+ # Uploading a file begins with getting a dynamic URL from the API.
107
+ EOS
108
+ end
109
+ upload_auth = session.send(
110
+ Bkblz::V1::GetUploadUrlRequest.new bucket.bucket_id).to_model
111
+ Bkblz.log.info "upload file URL => #{upload_auth.upload_url}"
112
+
113
+
114
+ Bkblz.log.info do <<-EOS
115
+ # Use the upload_auth model (a
116
+ # Bkblz::V1::Model::UploadAuth) to upload some files.
117
+ EOS
118
+ end
119
+ 5.times do |i|
120
+ body = "some text #{i}"
121
+ file_name = "some_text_#{i}.txt"
122
+ content_type = nil
123
+
124
+ upload_file_info = session.send(
125
+ Bkblz::V1::UploadFileRequest.new upload_auth, body, file_name,
101
126
  content_type, Time.now.to_i * 1000).to_model
102
- Bkblz.log.info "uploaded file => #{upload_file_info.file_name}"
103
- end
104
-
105
- Bkblz.log.info do <<-EOS
106
- # We uploaded 5 files above, here we'll read back out
107
- # metadata from the first 2 files in the bucket.
108
- EOS
109
- end
110
- list_files_response = api_session.send(
111
- Bkblz::V1::ListFileVersionsRequest.new bucket, 2)
112
- bucket_files_info = list_files_response.files
113
- Bkblz.log.info "first 2 files => #{bucket_files_info.map(&:file_name).join "\n"}"
114
-
115
- Bkblz.log.info do <<-EOS
116
- # The response object returned object is a
117
- # Bkblz::Api::PaginatedResponse. Use its +has_more?+ and
118
- # +next_request+ methods to page through more results.
119
- EOS
120
- end
121
- while list_files_response.has_more?
122
- list_files_response = api_session.send list_files_response.next_request 100
123
- bucket_files_info.concat list_files_response.files
124
- Bkblz.log.info "next N files => #{list_files_response.files.map(&:file_name).join "\n"}"
127
+ Bkblz.log.info "uploaded file => #{upload_file_info.file_name}"
128
+ end
129
+
130
+ Bkblz.log.info do <<-EOS
131
+ # We uploaded 5 files above, here we'll read back out
132
+ # metadata from the first 2 files in the bucket.
133
+ EOS
134
+ end
135
+ list_files_response = session.send(
136
+ Bkblz::V1::ListFileVersionsRequest.new bucket, 2)
137
+ bucket_files_info = list_files_response.files
138
+ Bkblz.log.info "first 2 files => #{bucket_files_info.map(&:file_name).join "\n"}"
139
+
140
+ Bkblz.log.info do <<-EOS
141
+ # The response object returned object is a
142
+ # Bkblz::Api::PaginatedResponse. Use its +has_more?+ and
143
+ # +next_request+ methods to page through more results.
144
+ EOS
145
+ end
146
+ while list_files_response.has_more?
147
+ list_files_response = session.send list_files_response.next_request 100
148
+ bucket_files_info.concat list_files_response.files
149
+ Bkblz.log.info "next N files => #{list_files_response.files.map(&:file_name).join "\n"}"
150
+ end
151
+
152
+ Bkblz.log.info do <<-EOS
153
+ # Files can also be listed by name.
154
+ EOS
155
+ end
156
+ list_files_response = session.send(
157
+ Bkblz::V1::ListFileNamesRequest.new bucket, 10)
158
+ bucket_files_info = list_files_response.files
159
+ Bkblz.log.info "files by name => #{bucket_files_info.map(&:file_name).join "\n"}"
160
+
161
+ Bkblz.log.info do <<-EOS
162
+ # Files can be downloaded by file name
163
+ EOS
164
+ end
165
+ file_name = bucket_files_info.first.file_name
166
+ file_name_download = session.send(
167
+ Bkblz::V1::DownloadFileByNameRequest.new bucket, file_name).to_model
168
+ Bkblz.log.info file_name_download
169
+ Bkblz.log.info "file body: #{file_name_download.body}"
170
+
171
+ Bkblz.log.info do <<-EOS
172
+ # Files can also be downloaded by file id
173
+ EOS
174
+ end
175
+ file_info = bucket_files_info[1]
176
+ file_id_download = session.send(
177
+ Bkblz::V1::DownloadFileByIdRequest.new file_info).to_model
178
+ Bkblz.log.info file_id_download
179
+ Bkblz.log.info "file body: #{file_id_download.body}"
180
+
181
+ Bkblz.log.info do <<-EOS
182
+ # File byte ranges can also be downloaded
183
+ EOS
184
+ end
185
+ bytes = (2..8)
186
+ byte_range_download = session.send(
187
+ Bkblz::V1::DownloadFileByNameRequest.new bucket, file_name, bytes).to_model
188
+ Bkblz.log.info "file bytes: #{byte_range_download.body}"
189
+ rescue => e
190
+ Bkblz.log.error "there was an error: #{e}"
191
+ Bkblz.log.error e.backtrace.join "\n"
192
+ Bkblz.log.warn "cleaning up the bucket"
193
+ ensure
194
+ clear_the_bucket session, bucket
195
+ end
125
196
  end
197
+ end
126
198
 
127
- Bkblz.log.info do <<-EOS
128
- # Files can also be listed by name.
129
- EOS
130
- end
131
- list_files_response = api_session.send(
132
- Bkblz::V1::ListFileNamesRequest.new bucket, 10)
199
+ def clear_the_bucket(session, bucket)
200
+ list_files_response = session.send(
201
+ Bkblz::V1::ListFileVersionsRequest.new bucket)
133
202
  bucket_files_info = list_files_response.files
134
- Bkblz.log.info "files by name => #{bucket_files_info.map(&:file_name).join "\n"}"
135
203
 
136
204
  Bkblz.log.info do <<-EOS
137
205
  # Delete all the files in the bucket that we added. This is
@@ -140,7 +208,7 @@ Bkblz::V1::Session.authorize Bkblz.config do |api_session|
140
208
  end
141
209
  bucket_files_info.each do |file_info|
142
210
  request = Bkblz::V1::DeleteFileVersionRequest.new file_info
143
- delete_file_version_response = api_session.send request
211
+ delete_file_version_response = session.send request
144
212
  Bkblz.log.info "deleted file => #{delete_file_version_response.to_model.file_name}"
145
213
  end
146
214
 
@@ -149,6 +217,8 @@ Bkblz::V1::Session.authorize Bkblz.config do |api_session|
149
217
  EOS
150
218
  end
151
219
  request = Bkblz::V1::DeleteBucketRequest.new bucket
152
- delete_bucket_response = api_session.send request
220
+ delete_bucket_response = session.send request
153
221
  Bkblz.log.info "deleted bucket => #{bucket.bucket_name}/#{bucket.bucket_id}"
154
222
  end
223
+
224
+ run_readme
data/bin/bkblz CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- $: << "lib"
3
2
  require "bkblz"
4
3
  require "thor"
5
4
  require "yaml"
@@ -83,8 +82,7 @@ module Bkblz
83
82
 
84
83
  file_info = run_task do
85
84
  Bkblz::Task::UploadFile.run Bkblz.config, {
86
- :bucket_handle => bucket_name,
87
- :handle_type => :bucket_name,
85
+ :bucket_name => bucket_name,
88
86
  :file_path => local_file_path
89
87
  }
90
88
  end
data/lib/bkblz/v1/all.rb CHANGED
@@ -15,3 +15,4 @@ require_relative "upload_file"
15
15
  require_relative "list_file_names"
16
16
  require_relative "list_file_versions"
17
17
  require_relative "delete_file_version"
18
+ require_relative "download_file"
@@ -0,0 +1,67 @@
1
+ module Bkblz
2
+ module V1
3
+
4
+ class DownloadFileResponse < Response
5
+ response_model Model::FileDownload
6
+
7
+ def parse(http_response)
8
+ file_download_fields = {
9
+ :body => http_response.body,
10
+ :content_length => http_response["content-length"],
11
+ :content_type => http_response["content-type"],
12
+ :file_id => http_response["x-bz-file-id"],
13
+ :file_name => http_response["x-bz-file-name"],
14
+ :sha1 => http_response["x-bz-content-sha1"],
15
+ :x_bz_info => {}
16
+ }
17
+
18
+ http_response.each_header do |k, v|
19
+ if k.to_s.downcase.match /^x-bz-info/
20
+ file_download_fields[:x_bz_info][k.to_sym] = v
21
+ end
22
+ end
23
+
24
+ file_download_fields
25
+ end
26
+ end
27
+
28
+ class DownloadFileByIdRequest < Request
29
+
30
+ response_class DownloadFileResponse
31
+ url_suffix "/b2api/v1/b2_download_file_by_id"
32
+
33
+ def initialize(file_info, byte_range=nil)
34
+ @body = {:file_id => file_info.file_id}
35
+ @byte_range = byte_range
36
+ end
37
+
38
+ def build_request(session)
39
+ headers = {}
40
+ headers[:Range] = "bytes=%d-%d" % @byte_range.minmax if @byte_range
41
+ session.create_post url(session), @body, headers
42
+ end
43
+ end
44
+
45
+ class DownloadFileByNameRequest < Request
46
+
47
+ response_class DownloadFileResponse
48
+
49
+ def initialize(bucket, file_name, byte_range=nil)
50
+ @bucket = bucket
51
+ @file_name = file_name
52
+ @byte_range = byte_range
53
+ end
54
+
55
+ def build_request(session)
56
+ headers = {}
57
+ headers[:Range] = "bytes=%d-%d" % @byte_range.minmax if @byte_range
58
+ session.create_get url_for_file(session), headers
59
+ end
60
+
61
+ private
62
+ def url_for_file(session)
63
+ session.create_url(["file", @bucket.bucket_name, @file_name].join "/")
64
+ end
65
+ end
66
+ end
67
+ end
@@ -10,6 +10,11 @@ module Bkblz
10
10
  :action, :content_length, :file_id, :file_name, :size, :upload_timestamp
11
11
  ]
12
12
 
13
+ # Returned by download_file_by_name and download_file_by_id
14
+ FileDownload = Model.define *[
15
+ :body, :content_length, :content_type, :file_id, :file_name, :sha1, :x_bz_info
16
+ ]
17
+
13
18
  # Returned by upload_file
14
19
  FileInfo = Model.define *[
15
20
  :account_id, :bucket_id, :content_length, :content_sha1, :content_type,
@@ -58,9 +58,10 @@ module Bkblz
58
58
  error_response = ErrorResponse.new response, self
59
59
  raise RequestError.create error_response
60
60
  end
61
- Bkblz.log.debug { "#build_response => #{response}" }
61
+ Bkblz.log.debug1(self) { "#build_response => #{response}" }
62
62
 
63
63
  response_class = self.class.response_class || Response
64
+ Bkblz.log.debug1(self) { "#creating response of class => #{response_class}" }
64
65
  response_class.new response, self
65
66
  end
66
67
 
@@ -70,7 +70,6 @@ module Bkblz
70
70
  self.class.response_model.new @parsed_response.dup
71
71
  end
72
72
 
73
- private
74
73
  def parse(http_response)
75
74
  parsed_json = JSON.parse http_response.body, {
76
75
  :allow_nan => true,
@@ -42,28 +42,44 @@ module Bkblz
42
42
  URI.join auth_response.api_url, url_suffix
43
43
  end
44
44
 
45
+ def create_get(url, addl_headers={})
46
+ Bkblz.log.debug { "creating GET for request => #{url}" }
47
+ check_authorized
48
+
49
+ request = Net::HTTP::Get.new uri_from_url(url)
50
+ add_request_headers request, addl_headers
51
+ request
52
+ end
53
+
45
54
  def create_post(url, body=nil, addl_headers={})
46
- Bkblz.log.debug { "creating post for request => #{url}" }
55
+ Bkblz.log.debug { "creating POST for request => #{url}" }
47
56
  check_authorized
48
57
 
49
- uri = url.is_a?(URI) ? url : URI(url)
50
- request = Net::HTTP::Post.new uri
58
+ request = Net::HTTP::Post.new uri_from_url(url)
51
59
 
52
60
  if body.is_a? Hash
53
61
  body = Bkblz::MapKeyFormatter.camelcase_keys(body).to_json
54
62
  end
55
63
  request.body = body if body
56
64
 
65
+ add_request_headers request, addl_headers
66
+
67
+ request
68
+ end
69
+
70
+ private
71
+ def uri_from_url(url)
72
+ url.is_a?(URI) ? url : URI(url)
73
+ end
74
+
75
+ def add_request_headers(request, addl_headers)
57
76
  headers = {:"Authorization" => auth_response.authorization_token}
58
77
  headers.merge(addl_headers).each do |k,v|
59
- Bkblz.log.debug2 { "adding request header => #{k}:#{v}" }
78
+ Bkblz.log.debug1(self) { "adding request header => #{k}:#{v}" }
60
79
  request.add_field k.to_s, v unless v.nil?
61
80
  end
62
-
63
- request
64
81
  end
65
82
 
66
- private
67
83
  def check_authorized
68
84
  raise SessionNotAuthorizedError unless authorized?
69
85
  end
data/lib/bkblz/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Bkblz
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bkblz
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Erick Johnson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-06 00:00:00.000000000 Z
11
+ date: 2016-11-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -101,6 +101,7 @@ files:
101
101
  - lib/bkblz/v1/create_bucket.rb
102
102
  - lib/bkblz/v1/delete_bucket.rb
103
103
  - lib/bkblz/v1/delete_file_version.rb
104
+ - lib/bkblz/v1/download_file.rb
104
105
  - lib/bkblz/v1/error_response.rb
105
106
  - lib/bkblz/v1/get_upload_url.rb
106
107
  - lib/bkblz/v1/list_buckets.rb