qoobaa-stree 0.1.0 → 0.2.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.
data/README.rdoc CHANGED
@@ -16,28 +16,28 @@ environment variables and uses them by default, so if you don't want
16
16
  to pass them each time, export them (e.g. in .bashrc file).
17
17
 
18
18
  * list buckets
19
- stree bucket
19
+ stree bucket
20
20
 
21
21
  * create bucket
22
- stree bucket add name-of-bucket
22
+ stree bucket add name-of-bucket
23
23
 
24
24
  * list objects in bucket
25
- stree bucket show name-of-bucket
25
+ stree bucket show name-of-bucket
26
26
 
27
27
  * destroy bucket
28
- stree bucket remove name-of-bucket
28
+ stree bucket remove name-of-bucket
29
29
 
30
30
  * list objects (in all buckets)
31
- stree object
31
+ stree object
32
32
 
33
33
  * show the object information
34
- stree object show bucket_name/path/to/object.extension
34
+ stree object show bucket_name/path/to/object.extension
35
35
 
36
36
  * download the content of the object
37
- stree object show bucket_name/path/to/object.extension filename_to_store_the_content.extension
37
+ stree object show bucket_name/path/to/object.extension filename_to_store_the_content.extension
38
38
 
39
39
  * show the content of the object to STDOUT
40
- stree object show bucket_name/path/to/object.extension -
40
+ stree object show bucket_name/path/to/object.extension -
41
41
 
42
42
  You can also pass --help to the commmands like:
43
43
  stree bucket add --help
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -103,7 +103,7 @@ module Technoweenie
103
103
  # :nodoc:
104
104
  def current_data
105
105
  # Object.value full_filename, bucket_name
106
- object = self.class.bucket.find(full_filename)
106
+ object = self.class.bucket.objects.find(full_filename)
107
107
  object.content
108
108
  end
109
109
 
data/lib/stree/bucket.rb CHANGED
@@ -1,25 +1,26 @@
1
1
  module Stree
2
2
  class Bucket
3
+ include Parser
3
4
  extend Roxy::Moxie
4
5
  extend Forwardable
5
6
 
6
7
  attr_reader :name, :service
7
8
 
8
9
  def_instance_delegators :service, :service_request
10
+ private_class_method :new
9
11
 
10
12
  # Retrieves the bucket information from the server. Raises an
11
13
  # Stree::Error exception if the bucket doesn't exist or you don't
12
14
  # have access to it, etc.
13
15
  def retrieve
14
- bucket_request(:get, :params => { :max_keys => 0 })
16
+ list_bucket(:max_keys => 0)
15
17
  self
16
18
  end
17
19
 
18
20
  # Returns location of the bucket, e.g. "EU"
19
21
  def location(reload = false)
20
22
  if reload or @location.nil?
21
- response = bucket_request(:get, :params => { :location => nil })
22
- @location = parse_location(response.body)
23
+ @location = location_constraint
23
24
  else
24
25
  @location
25
26
  end
@@ -45,7 +46,7 @@ module Stree
45
46
  # bucket is not empty. You can destroy non-empty bucket passing
46
47
  # true (to force destroy)
47
48
  def destroy(force = false)
48
- bucket_request(:delete)
49
+ delete_bucket
49
50
  true
50
51
  rescue Error::BucketNotEmpty
51
52
  if force
@@ -59,13 +60,7 @@ module Stree
59
60
  # Saves the newly built bucket. Optionally you can pass location
60
61
  # of the bucket (:eu or :us)
61
62
  def save(location = nil)
62
- location = location.to_s.upcase if location
63
- options = { :headers => {} }
64
- if location and location != "US"
65
- options[:body] = "<CreateBucketConfiguration><LocationConstraint>#{location}</LocationConstraint></CreateBucketConfiguration>"
66
- options[:headers][:content_type] = "application/xml"
67
- end
68
- bucket_request(:put, options)
63
+ create_bucket_configuration(location)
69
64
  true
70
65
  end
71
66
 
@@ -92,7 +87,7 @@ module Stree
92
87
  # reload).
93
88
  def objects(reload = false)
94
89
  if reload or @objects.nil?
95
- @objects = fetch_objects
90
+ @objects = list_bucket
96
91
  else
97
92
  @objects
98
93
  end
@@ -102,7 +97,7 @@ module Stree
102
97
 
103
98
  # Builds the object in the bucket with given key
104
99
  def build(key)
105
- Object.new(proxy_owner, key)
100
+ Object.send(:new, proxy_owner, :key => key)
106
101
  end
107
102
 
108
103
  # Finds first object with given name or raises the exception if
@@ -120,7 +115,7 @@ module Stree
120
115
  # +max_keys+:: The maximum number of keys you'd like to see
121
116
  # +delimiter+:: Causes keys that contain the same string between the prefix and the first occurrence of the delimiter to be rolled up into a single result element
122
117
  def find_all(options = {})
123
- proxy_owner.send(:fetch_objects, options)
118
+ proxy_owner.send(:list_bucket, options)
124
119
  end
125
120
 
126
121
  # Reloads the object list (clears the cache)
@@ -140,15 +135,40 @@ module Stree
140
135
  "#<#{self.class}:#{name}>"
141
136
  end
142
137
 
138
+ private
139
+
140
+ attr_writer :service
141
+
142
+ def location_constraint
143
+ response = bucket_request(:get, :params => { :location => nil })
144
+ parse_location_constraint(response.body)
145
+ end
146
+
147
+ def list_bucket(options = {})
148
+ response = bucket_request(:get, :params => options)
149
+ objects_attributes = parse_list_bucket_result(response.body)
150
+ objects_attributes.map { |object_attributes| Object.send(:new, self, object_attributes) }
151
+ end
152
+
153
+ def create_bucket_configuration(location = nil)
154
+ location = location.to_s.upcase if location
155
+ options = { :headers => {} }
156
+ if location and location != "US"
157
+ options[:body] = "<CreateBucketConfiguration><LocationConstraint>#{location}</LocationConstraint></CreateBucketConfiguration>"
158
+ options[:headers][:content_type] = "application/xml"
159
+ end
160
+ bucket_request(:put, options)
161
+ end
162
+
163
+ def delete_bucket
164
+ bucket_request(:delete)
165
+ end
166
+
143
167
  def initialize(service, name) #:nodoc:
144
168
  self.service = service
145
169
  self.name = name
146
170
  end
147
171
 
148
- private
149
-
150
- attr_writer :service
151
-
152
172
  def name=(name)
153
173
  raise ArgumentError.new("Invalid bucket name: #{name}") unless name_valid?(name)
154
174
  @name = name
@@ -159,32 +179,6 @@ module Stree
159
179
  service_request(method, options.merge(:host => host, :path => path))
160
180
  end
161
181
 
162
- def fetch_objects(options = {})
163
- response = bucket_request(:get, options)
164
- parse_objects(response.body)
165
- end
166
-
167
- def parse_objects(xml_body)
168
- xml = XmlSimple.xml_in(xml_body)
169
- objects_attributes = xml["Contents"]
170
- if objects_attributes
171
- objects_attributes.map do |object_attributes|
172
- Object.new(self,
173
- object_attributes["Key"].first,
174
- :etag => object_attributes["ETag"].first,
175
- :last_modified => object_attributes["LastModified"].first,
176
- :size => object_attributes["Size"].first)
177
- end
178
- else
179
- []
180
- end
181
- end
182
-
183
- def parse_location(xml_body)
184
- xml = XmlSimple.xml_in(xml_body)
185
- xml["content"]
186
- end
187
-
188
182
  def name_valid?(name)
189
183
  name =~ /\A[a-z0-9][a-z0-9\._-]{2,254}\Z/ and name !~ /\A#{URI::REGEXP::PATTERN::IPV4ADDR}\Z/
190
184
  end
@@ -2,6 +2,8 @@ module Stree
2
2
 
3
3
  # Class responsible for handling connections to amazon hosts
4
4
  class Connection
5
+ include Parser
6
+
5
7
  attr_accessor :access_key_id, :secret_access_key, :use_ssl, :timeout, :debug
6
8
  alias :use_ssl? :use_ssl
7
9
 
@@ -185,9 +187,7 @@ module Stree
185
187
  if response.body.nil? || response.body.empty?
186
188
  raise Error::ResponseError.new(nil, response)
187
189
  else
188
- xml = XmlSimple.xml_in(response.body)
189
- message = xml["Message"].first
190
- code = xml["Code"].first
190
+ code, message = parse_error(response.body)
191
191
  raise Error::ResponseError.exception(code).new(message, response)
192
192
  end
193
193
  else
data/lib/stree/object.rb CHANGED
@@ -2,6 +2,7 @@ module Stree
2
2
 
3
3
  # Class responsible for handling objects stored in S3 buckets
4
4
  class Object
5
+ include Parser
5
6
  extend Forwardable
6
7
 
7
8
  attr_accessor :content_type, :content_disposition, :content_encoding
@@ -10,6 +11,7 @@ module Stree
10
11
 
11
12
  def_instance_delegators :bucket, :name, :service, :bucket_request, :vhost?, :host, :path_prefix
12
13
  def_instance_delegators :service, :protocol, :port
14
+ private_class_method :new
13
15
 
14
16
  # Compares the object with other object. Returns true if the key
15
17
  # of the objects are the same, and both have the same buckets (see
@@ -43,8 +45,7 @@ module Stree
43
45
  # NOT download the content of the object (use the content method
44
46
  # to do it).
45
47
  def retrieve
46
- response = object_request(:get, :headers => { :range => 0..0 })
47
- parse_headers(response)
48
+ get_object(:headers => { :range => 0..0 })
48
49
  self
49
50
  end
50
51
 
@@ -62,18 +63,14 @@ module Stree
62
63
  # to clear the cache and download the object again.
63
64
  def content(reload = false)
64
65
  if reload or @content.nil?
65
- response = object_request(:get)
66
- parse_headers(response)
67
- self.content = response.body
66
+ get_object
68
67
  end
69
68
  @content
70
69
  end
71
70
 
72
71
  # Saves the object, returns true if successfull.
73
72
  def save
74
- body = content.is_a?(IO) ? content.read : content
75
- response = object_request(:put, :body => body, :headers => dump_headers)
76
- parse_headers(response)
73
+ put_object
77
74
  true
78
75
  end
79
76
 
@@ -84,28 +81,12 @@ module Stree
84
81
  # +acl+:: acl of the copied object (default: "public-read")
85
82
  # +content_type+:: content type of the copied object (default: "application/octet-stream")
86
83
  def copy(options = {})
87
- key = options[:key] || self.key
88
- bucket = options[:bucket] || self.bucket
89
-
90
- headers = {}
91
- headers[:x_amz_acl] = options[:acl] || acl || "public-read"
92
- headers[:content_type] = options[:content_type] || content_type || "application/octet-stream"
93
- headers[:content_encoding] = options[:content_encoding] if options[:content_encoding]
94
- headers[:content_disposition] = options[:content_disposition] if options[:content_disposition]
95
- headers[:x_amz_copy_source] = full_key
96
- headers[:x_amz_metadata_directive] = "REPLACE"
97
- headers[:x_amz_copy_source_if_match] = options[:if_match] if options[:if_match]
98
- headers[:x_amz_copy_source_if_none_match] = options[:if_none_match] if options[:if_none_match]
99
- headers[:x_amz_copy_source_if_unmodified_since] = options[:if_modified_since] if options[:if_modified_since]
100
- headers[:x_amz_copy_source_if_modified_since] = options[:if_unmodified_since] if options[:if_unmodified_since]
101
-
102
- response = bucket.send(:bucket_request, :put, :path => key, :headers => headers)
103
- self.class.parse_copied(:object => self, :bucket => bucket, :key => key, :body => response.body, :headers => headers)
84
+ copy_object(options)
104
85
  end
105
86
 
106
87
  # Destroys the file on the server
107
88
  def destroy
108
- object_request(:delete)
89
+ delete_object
109
90
  true
110
91
  end
111
92
 
@@ -127,18 +108,62 @@ module Stree
127
108
  "#<#{self.class}:/#{name}/#{key}>"
128
109
  end
129
110
 
130
- def initialize(bucket, key, options = {}) #:nodoc:
111
+ private
112
+
113
+ attr_writer :last_modified, :etag, :size, :original_key, :bucket
114
+
115
+ def copy_object(options = {})
116
+ key = options[:key] or raise ArgumentError, "No key given"
117
+ raise ArgumentError.new("Invalid key name: #{key}") unless key_valid?(key)
118
+ bucket = options[:bucket] || self.bucket
119
+
120
+ headers = {}
121
+
122
+ headers[:x_amz_acl] = options[:acl] || acl || "public-read"
123
+ headers[:content_type] = options[:content_type] || content_type || "application/octet-stream"
124
+ headers[:content_encoding] = options[:content_encoding] if options[:content_encoding]
125
+ headers[:content_disposition] = options[:content_disposition] if options[:content_disposition]
126
+ headers[:x_amz_copy_source] = full_key
127
+ headers[:x_amz_metadata_directive] = "REPLACE"
128
+ headers[:x_amz_copy_source_if_match] = options[:if_match] if options[:if_match]
129
+ headers[:x_amz_copy_source_if_none_match] = options[:if_none_match] if options[:if_none_match]
130
+ headers[:x_amz_copy_source_if_unmodified_since] = options[:if_modified_since] if options[:if_modified_since]
131
+ headers[:x_amz_copy_source_if_modified_since] = options[:if_unmodified_since] if options[:if_unmodified_since]
132
+
133
+ response = bucket.send(:bucket_request, :put, :path => key, :headers => headers)
134
+ object_attributes = parse_copy_object_result(response.body)
135
+
136
+ object = Object.send(:new, bucket, object_attributes.merge(:key => key, :size => size))
137
+ object.acl = response[:x_amz_acl]
138
+ object.content_type = response[:content_type]
139
+ object.content_encoding = response[:content_encoding]
140
+ object.content_disposition = response[:content_disposition]
141
+ object
142
+ end
143
+
144
+ def get_object(options = {})
145
+ response = object_request(:get, options)
146
+ parse_headers(response)
147
+ end
148
+
149
+ def put_object
150
+ body = content.is_a?(IO) ? content.read : content
151
+ response = object_request(:put, :body => body, :headers => dump_headers)
152
+ parse_headers(response)
153
+ end
154
+
155
+ def delete_object(options = {})
156
+ object_request(:delete)
157
+ end
158
+
159
+ def initialize(bucket, options = {})
131
160
  self.bucket = bucket
132
- self.key = key
161
+ self.key = options[:key]
133
162
  self.last_modified = options[:last_modified]
134
163
  self.etag = options[:etag]
135
164
  self.size = options[:size]
136
165
  end
137
166
 
138
- private
139
-
140
- attr_writer :last_modified, :etag, :size, :original_key, :bucket
141
-
142
167
  def object_request(method, options = {})
143
168
  bucket_request(method, options.merge(:path => key))
144
169
  end
@@ -151,6 +176,14 @@ module Stree
151
176
  @etag = etag[1..-2] if etag
152
177
  end
153
178
 
179
+ def key_valid?(key)
180
+ if (key.nil? or key.empty? or key =~ %r#//#)
181
+ false
182
+ else
183
+ true
184
+ end
185
+ end
186
+
154
187
  def dump_headers
155
188
  headers = {}
156
189
  headers[:x_amz_acl] = @acl || "public-read"
@@ -160,37 +193,18 @@ module Stree
160
193
  headers
161
194
  end
162
195
 
163
- def key_valid?(key)
164
- if (key.nil? or key.empty? or key =~ %r#//#)
165
- false
166
- else
167
- true
168
- end
169
- end
170
-
171
196
  def parse_headers(response)
172
197
  self.etag = response["etag"]
173
198
  self.content_type = response["content-type"]
174
199
  self.content_disposition = response["content-disposition"]
175
200
  self.content_encoding = response["content-encoding"]
176
201
  self.last_modified = response["last-modified"]
177
- self.size = response["content-length"]
178
202
  if response["content-range"]
179
203
  self.size = response["content-range"].sub(/[^\/]+\//, "").to_i
204
+ else
205
+ self.size = response["content-length"]
206
+ self.content = response.body
180
207
  end
181
208
  end
182
-
183
- def self.parse_copied(options)
184
- xml = XmlSimple.xml_in(options[:body])
185
- etag = xml["ETag"].first
186
- last_modified = xml["LastModified"].first
187
- size = options[:object].size
188
- object = Object.new(options[:bucket], options[:key], :etag => etag, :last_modified => last_modified, :size => size)
189
- object.acl = options[:headers][:x_amz_acl]
190
- object.content_type = options[:headers][:content_type]
191
- object.content_encoding = options[:headers][:content_encoding]
192
- object.content_disposition = options[:headers][:content_disposition]
193
- object
194
- end
195
209
  end
196
210
  end
@@ -0,0 +1,48 @@
1
+ module Stree
2
+ module Parser
3
+ include REXML
4
+
5
+ def rexml_document(xml)
6
+ xml.force_encoding(Encoding::UTF_8) if xml.respond_to? :force_encoding
7
+ Document.new(xml)
8
+ end
9
+
10
+ def parse_list_all_my_buckets_result(xml)
11
+ names = []
12
+ rexml_document(xml).elements.each("ListAllMyBucketsResult/Buckets/Bucket/Name") { |e| names << e.text }
13
+ names
14
+ end
15
+
16
+ def parse_location_constraint(xml)
17
+ rexml_document(xml).elements["LocationConstraint"].text
18
+ end
19
+
20
+ def parse_list_bucket_result(xml)
21
+ objects_attributes = []
22
+ rexml_document(xml).elements.each("ListBucketResult/Contents") do |e|
23
+ object_attributes = {}
24
+ object_attributes[:key] = e.elements["Key"].text
25
+ object_attributes[:etag] = e.elements["ETag"].text
26
+ object_attributes[:last_modified] = e.elements["LastModified"].text
27
+ object_attributes[:size] = e.elements["Size"].text
28
+ objects_attributes << object_attributes
29
+ end
30
+ objects_attributes
31
+ end
32
+
33
+ def parse_copy_object_result(xml)
34
+ object_attributes = {}
35
+ document = rexml_document(xml)
36
+ object_attributes[:etag] = document.elements["CopyObjectResult/ETag"].text
37
+ object_attributes[:last_modified] = document.elements["CopyObjectResult/LastModified"].text
38
+ object_attributes
39
+ end
40
+
41
+ def parse_error(xml)
42
+ document = rexml_document(xml)
43
+ code = document.elements["Error/Code"].text
44
+ message = document.elements["Error/Message"].text
45
+ [code, message]
46
+ end
47
+ end
48
+ end
data/lib/stree/service.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  module Stree
2
2
  class Service
3
+ include Parser
3
4
  extend Roxy::Moxie
4
5
 
5
6
  attr_reader :access_key_id, :secret_access_key, :use_ssl
@@ -19,8 +20,8 @@ module Stree
19
20
  # +timeout+:: parameter for Net::HTTP module
20
21
  # +debug+:: prints the raw requests to STDOUT
21
22
  def initialize(options)
22
- @access_key_id = options[:access_key_id] or raise ArgumentError.new("No access key id given")
23
- @secret_access_key = options[:secret_access_key] or raise ArgumentError.new("No secret access key given")
23
+ @access_key_id = options[:access_key_id] or raise ArgumentError, "No access key id given"
24
+ @secret_access_key = options[:secret_access_key] or raise ArgumentError, "No secret access key given"
24
25
  @use_ssl = options[:use_ssl]
25
26
  @timeout = options[:timeout]
26
27
  @debug = options[:debug]
@@ -29,8 +30,7 @@ module Stree
29
30
  # Returns all buckets in the service and caches the result (see reload)
30
31
  def buckets(reload = false)
31
32
  if reload or @buckets.nil?
32
- response = service_request(:get)
33
- @buckets = parse_buckets(response.body)
33
+ @buckets = list_all_my_buckets
34
34
  else
35
35
  @buckets
36
36
  end
@@ -49,7 +49,7 @@ module Stree
49
49
  proxy :buckets do
50
50
  # Builds new bucket with given name
51
51
  def build(name)
52
- Bucket.new(proxy_owner, name)
52
+ Bucket.send(:new, proxy_owner, name)
53
53
  end
54
54
 
55
55
  # Finds the bucket with given name
@@ -85,6 +85,12 @@ module Stree
85
85
 
86
86
  private
87
87
 
88
+ def list_all_my_buckets
89
+ response = service_request(:get)
90
+ names = parse_list_all_my_buckets_result(response.body)
91
+ names.map { |name| Bucket.send(:new, self, name) }
92
+ end
93
+
88
94
  def service_request(method, options = {})
89
95
  connection.request(method, options.merge(:path => "/#{options[:path]}"))
90
96
  end
@@ -100,18 +106,5 @@ module Stree
100
106
  end
101
107
  @connection
102
108
  end
103
-
104
- def parse_buckets(xml_body)
105
- xml = XmlSimple.xml_in(xml_body)
106
- buckets = xml["Buckets"].first["Bucket"]
107
- if buckets
108
- buckets_names = buckets.map { |bucket| bucket["Name"].first }
109
- buckets_names.map do |bucket_name|
110
- Bucket.new(self, bucket_name)
111
- end
112
- else
113
- []
114
- end
115
- end
116
109
  end
117
110
  end
data/lib/stree.rb CHANGED
@@ -1,16 +1,16 @@
1
- require "time"
2
- require "openssl"
3
- require "net/http"
4
- require "net/https"
5
1
  require "base64"
6
- require "forwardable"
7
2
  require "digest/md5"
3
+ require "forwardable"
4
+ require "net/http"
5
+ require "net/https"
6
+ require "openssl"
7
+ require "rexml/document"
8
+ require "time"
8
9
 
9
- require "xmlsimple"
10
-
11
- require "stree/roxy/proxy"
12
10
  require "stree/roxy/moxie"
11
+ require "stree/roxy/proxy"
13
12
 
13
+ require "stree/parser"
14
14
  require "stree/bucket"
15
15
  require "stree/connection"
16
16
  require "stree/exceptions"
data/stree.gemspec CHANGED
@@ -1,12 +1,15 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
1
4
  # -*- encoding: utf-8 -*-
2
5
 
3
6
  Gem::Specification.new do |s|
4
7
  s.name = %q{stree}
5
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
6
9
 
7
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
11
  s.authors = ["Jakub Kuźma", "Mirosław Boruta"]
9
- s.date = %q{2009-07-13}
12
+ s.date = %q{2009-08-19}
10
13
  s.default_executable = %q{stree}
11
14
  s.email = %q{qoobaa@gmail.com}
12
15
  s.executables = ["stree"]
@@ -28,6 +31,7 @@ Gem::Specification.new do |s|
28
31
  "lib/stree/connection.rb",
29
32
  "lib/stree/exceptions.rb",
30
33
  "lib/stree/object.rb",
34
+ "lib/stree/parser.rb",
31
35
  "lib/stree/roxy/moxie.rb",
32
36
  "lib/stree/roxy/proxy.rb",
33
37
  "lib/stree/service.rb",
@@ -43,7 +47,7 @@ Gem::Specification.new do |s|
43
47
  s.homepage = %q{http://github.com/qoobaa/stree}
44
48
  s.rdoc_options = ["--charset=UTF-8"]
45
49
  s.require_paths = ["lib"]
46
- s.rubygems_version = %q{1.3.4}
50
+ s.rubygems_version = %q{1.3.5}
47
51
  s.summary = %q{Library for accessing S3 objects and buckets, with command line tool}
48
52
  s.test_files = [
49
53
  "test/bucket_test.rb",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qoobaa-stree
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Jakub Ku\xC5\xBAma"
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-07-13 00:00:00 -07:00
13
+ date: 2009-08-19 00:00:00 -07:00
14
14
  default_executable: stree
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -46,6 +46,7 @@ files:
46
46
  - lib/stree/connection.rb
47
47
  - lib/stree/exceptions.rb
48
48
  - lib/stree/object.rb
49
+ - lib/stree/parser.rb
49
50
  - lib/stree/roxy/moxie.rb
50
51
  - lib/stree/roxy/proxy.rb
51
52
  - lib/stree/service.rb
@@ -59,6 +60,7 @@ files:
59
60
  - test/test_helper.rb
60
61
  has_rdoc: false
61
62
  homepage: http://github.com/qoobaa/stree
63
+ licenses:
62
64
  post_install_message:
63
65
  rdoc_options:
64
66
  - --charset=UTF-8
@@ -79,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
81
  requirements: []
80
82
 
81
83
  rubyforge_project:
82
- rubygems_version: 1.2.0
84
+ rubygems_version: 1.3.5
83
85
  signing_key:
84
86
  specification_version: 3
85
87
  summary: Library for accessing S3 objects and buckets, with command line tool