bkblz 0.1.2 → 0.1.4

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