waz-storage 1.0.6 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -120,6 +120,22 @@ module WAZ
120
120
  :url => self.class.service_instance.generate_request_uri("#{self.name}/#{blob_name}"),
121
121
  :content_type => content_type)
122
122
  end
123
+
124
+ # Uploads the contents of a stream to the specified blob within this container, using
125
+ # the required <em>content_type</em>. The stream will be uploaded in blocks of size
126
+ # <em>block_size</em> bytes, which defaults to four megabytes. <strong>The <em>options</em>
127
+ # parameter, if provided, will set the default metadata properties for the blob</strong>.
128
+ def upload(blob_name, stream, content_type, options = {}, block_size = 4 * 2**20)
129
+ blob_name.gsub!(%r{^/}, '')
130
+ path = "#{self.name}/#{blob_name}"
131
+ n = 0
132
+ until stream.eof?
133
+ self.class.service_instance.put_block path, Base64.encode64('%064d' % n), stream.read(block_size)
134
+ n += 1
135
+ end
136
+ self.class.service_instance.put_block_list path, (0...n).map{|id| Base64.encode64('%064d' % id)}, content_type, options
137
+ return BlobObject.new(:name => blob_name, :url => self.class.service_instance.generate_request_uri("#{self.name}/#{blob_name}"), :content_type => content_type)
138
+ end
123
139
 
124
140
  # Retrieves the blob by the given name. If the blob isn't found on the current container
125
141
  # it will return nil instead of throwing an exception.
@@ -136,4 +152,4 @@ module WAZ
136
152
  end
137
153
  end
138
154
  end
139
- end
155
+ end
@@ -83,7 +83,19 @@ module WAZ
83
83
  default_headers = {"Content-Type" => content_type, :x_ms_version => "2009-09-19", :x_ms_blob_type => "BlockBlob"}
84
84
  execute :put, path, nil, metadata.merge(default_headers), payload
85
85
  end
86
-
86
+
87
+ # Commits a list of blocks to the given blob.
88
+ #
89
+ # blockids is a list of valid, already-uploaded block IDs (base64-encoded)
90
+ #
91
+ # content_type is required by the blobs api, but on this method is defaulted to "application/octect-stream"
92
+ #
93
+ # metadata is a hash that stores all the properties that you want to add to the blob when creating it.
94
+ def put_block_list(path, blockids, content_type = "application/octet-stream", metadata = {})
95
+ default_headers = {"Content-Type" => content_type, :x_ms_version => "2009-09-19"}
96
+ execute :put, path, { :comp => 'blocklist' }, metadata.merge(default_headers), '<?xml version="1.0" encoding="utf-8"?><BlockList>' + blockids.map {|id| "<Latest>#{id.rstrip}</Latest>"}.join + '</BlockList>'
97
+ end
98
+
87
99
  # Retrieves a blob (content + headers) from the current path.
88
100
  def get_blob(path, options = {})
89
101
  execute :get, path, options, {:x_ms_version => "2009-09-19"}
@@ -58,7 +58,7 @@ module WAZ
58
58
  # Creates a canonical representation of the message by combining account_name/resource_path.
59
59
  def canonicalize_message(url)
60
60
  uri_component = url.gsub(/https?:\/\/[^\/]+\//i, '').gsub(/\?.*/i, '')
61
- comp_component = url.scan(/(comp=[^&]+)/i).first()
61
+ comp_component = url.scan(/comp=[^&]+/i).first()
62
62
  uri_component << "?#{comp_component}" if comp_component
63
63
  canonicalized_message = "/#{self.account_name}/#{uri_component}"
64
64
  return canonicalized_message
@@ -104,7 +104,7 @@ module WAZ
104
104
  def canonicalize_message20090919(url)
105
105
  uri_component = url.gsub(/https?:\/\/[^\/]+\//i, '').gsub(/\?.*/i, '')
106
106
  query_component = (url.scan(/\?(.*)/i).first() or []).first()
107
- query_component = query_component.split('&').sort{|a, b| a <=> b}.map{ |p| p.split('=').join(':') }.join("\n") if query_component
107
+ query_component = query_component.split('&').sort{|a, b| a <=> b}.map{ |p| CGI::unescape(p.split('=').join(':')) }.join("\n") if query_component
108
108
  canonicalized_message = "/#{self.account_name}/#{uri_component}"
109
109
  canonicalized_message << "\n#{query_component}" if query_component
110
110
  return canonicalized_message
@@ -2,8 +2,8 @@ module WAZ
2
2
  module Storage
3
3
  module VERSION #:nodoc:
4
4
  MAJOR = '1'
5
- MINOR = '0'
6
- TINY = '6'
5
+ MINOR = '1'
6
+ TINY = '0'
7
7
  end
8
8
 
9
9
  Version = [VERSION::MAJOR, VERSION::MINOR, VERSION::TINY].compact * '.'
@@ -139,17 +139,17 @@ module WAZ
139
139
  def generate_payload(table_name, entity)
140
140
  payload = "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" \
141
141
  "<entry xmlns:d=\"#{DATASERVICES_NAMESPACE}\" xmlns:m=\"#{DATASERVICES_METADATA_NAMESPACE}\" xmlns=\"http://www.w3.org/2005/Atom\">" \
142
- "<id>#{generate_request_uri "#{table_name}"}(PartitionKey='#{entity[:partition_key]}',RowKey='#{entity[:row_key]}')</id>" \
143
- "<title /><updated>#{Time.now.utc.iso8601}</updated><author><name /></author><link rel=\"edit\" title=\"#{table_name}\" href=\"#{table_name}(PartitionKey='#{entity[:partition_key]}',RowKey='#{entity[:row_key]}')\" />" \
142
+ "<id>#{generate_request_uri "#{table_name}"}(PartitionKey='#{REXML::Text.new(entity[:partition_key], false, nil, false).to_s}',RowKey='#{REXML::Text.new(entity[:row_key], false, nil, false).to_s}')</id>" \
143
+ "<title /><updated>#{Time.now.utc.iso8601}</updated><author><name /></author><link rel=\"edit\" title=\"#{table_name}\" href=\"#{table_name}(PartitionKey='#{REXML::Text.new(entity[:partition_key], false, nil, false).to_s}',RowKey='#{REXML::Text.new(entity[:row_key], false, nil, false).to_s}')\" />" \
144
144
  "<content type=\"application/xml\"><m:properties>"
145
145
 
146
146
  entity.sort_by { |k| k.to_s }.each do |k,v|
147
147
  value, type = EdmTypeHelper.parse_to(v)[0].to_s, EdmTypeHelper.parse_to(v)[1].to_s
148
- payload << (!v.nil? ? "<d:#{k.to_s} m:type=\"#{k.edm_type || type}\">#{value}</d:#{k.to_s}>" : "<d:#{k.to_s} m:type=\"#{k.edm_type || type}\" m:null=\"true\" />") unless k.eql?(:partition_key) or k.eql?(:row_key)
148
+ payload << (!v.nil? ? "<d:#{k.to_s} m:type=\"#{k.edm_type || type}\">#{REXML::Text.new(value, false, nil, false).to_s}</d:#{k.to_s}>" : "<d:#{k.to_s} m:type=\"#{k.edm_type || type}\" m:null=\"true\" />") unless k.eql?(:partition_key) or k.eql?(:row_key)
149
149
  end
150
150
 
151
- payload << "<d:PartitionKey>#{entity[:partition_key]}</d:PartitionKey>" \
152
- "<d:RowKey>#{entity[:row_key]}</d:RowKey>" \
151
+ payload << "<d:PartitionKey>#{REXML::Text.new(entity[:partition_key], false, nil, false).to_s}</d:PartitionKey>" \
152
+ "<d:RowKey>#{REXML::Text.new(entity[:row_key], false, nil, false).to_s}</d:RowKey>" \
153
153
  "</m:properties></content></entry>"
154
154
  return payload
155
155
  end
@@ -175,4 +175,4 @@ module WAZ
175
175
  end
176
176
  end
177
177
  end
178
- end
178
+ end
data/rakefile CHANGED
@@ -44,7 +44,7 @@ end
44
44
  namespace :docs do
45
45
  Rake::RDocTask.new do |t|
46
46
  t.rdoc_dir = 'rdoc'
47
- t.title = "Windows Azure Storage library simple gem for accessing WAZs Storage REST API"
47
+ t.title = "Windows Azure Storage library - simple gem for accessing WAZ's Storage REST API"
48
48
  t.options << '--line-numbers' << '--inline-source' << '-A cattr_accessor=object'
49
49
  t.options << '--charset' << 'utf-8'
50
50
  t.rdoc_files.include('README.rdoc')
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: waz-storage
3
3
  version: !ruby/object:Gem::Version
4
- hash: 27
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
+ - 1
8
9
  - 0
9
- - 6
10
- version: 1.0.6
10
+ version: 1.1.0
11
11
  platform: ruby
12
12
  authors:
13
13
  - Johnny G. Halife
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-05-18 00:00:00 -04:00
18
+ date: 2011-06-29 00:00:00 -03:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency