diff --git a/lib/remote_storage/riak.rb b/lib/remote_storage/riak.rb index 99055d8..14d485c 100644 --- a/lib/remote_storage/riak.rb +++ b/lib/remote_storage/riak.rb @@ -238,26 +238,25 @@ module RemoteStorage end def directory_listing(user, directory) - listing = {} + listing = { + "@context" => "http://remotestorage.io/spec/folder-description", + "items" => {} + } sub_directories(user, directory).each do |entry| directory_name = entry["name"].split("/").last - timestamp = entry["timestamp"].to_i etag = entry["etag"] - listing.merge!({ "#{directory_name}/" => etag }) + listing["items"].merge!({ "#{directory_name}/" => { "ETag" => etag }}) end directory_entries(user, directory).each do |entry| entry_name = entry["name"] - timestamp = if entry["timestamp"] - entry["timestamp"].to_i - else - DateTime.rfc2822(entry["last_modified"]).to_time.to_i - end etag = entry["etag"] + content_type = entry["contentType"] + content_length = entry["contentLength"].to_i - listing.merge!({ entry_name => etag }) + listing["items"].merge!({ entry_name => { "ETag" => etag, "Content-Type" => content_type, "Content-Length" => content_length }}) end listing @@ -269,17 +268,20 @@ module RemoteStorage map_query = <<-EOH function(v){ - keys = v.key.split(':'); + var values = v.values[0]; + var metadata = values['metadata']; + var keys = v.key.split(':'); keys.splice(0, 2); - key_name = keys.join(':'); - last_modified_date = v.values[0]['metadata']['X-Riak-Last-Modified']; - timestamp = v.values[0]['metadata']['X-Riak-Meta']['X-Riak-Meta-Timestamp']; - etag = v.values[0]['metadata']['X-Riak-VTag']; + var key_name = keys.join(':'); + var etag = metadata['X-Riak-VTag']; + var contentType = metadata['content-type']; + var contentLength = metadata['X-Riak-Meta']['X-Riak-Meta-Content_length'] || 0; + return [{ name: key_name, - last_modified: last_modified_date, - timestamp: timestamp, - etag: etag + etag: etag, + contentType: contentType, + contentLength: contentLength }]; } EOH @@ -293,13 +295,12 @@ module RemoteStorage map_query = <<-EOH function(v){ - keys = v.key.split(':'); - key_name = keys[keys.length-1]; - timestamp = v.values[0]['data']; - etag = v.values[0]['metadata']['X-Riak-VTag']; + var keys = v.key.split(':'); + var key_name = keys[keys.length-1]; + var etag = v.values[0]['metadata']['X-Riak-VTag']; + return [{ name: key_name, - timestamp: timestamp, etag: etag }]; } @@ -370,6 +371,8 @@ module RemoteStorage data = JSON.parse(data) end + object.meta["content_length"] = data.size + if serializer_for(object.content_type) object.data = data else @@ -387,6 +390,7 @@ module RemoteStorage ) object.meta["binary_key"] = cs_binary_object.key + object.meta["content_length"] = cs_binary_object.content_length object.raw_data = "" end diff --git a/spec/directories_spec.rb b/spec/directories_spec.rb index 19ea715..035586f 100644 --- a/spec/directories_spec.rb +++ b/spec/directories_spec.rb @@ -19,7 +19,7 @@ describe "Directories" do put "/jimmy/tasks/http%3A%2F%2F5apps.com", "prettify design" end - it "lists the objects with their version" do + it "lists the objects with version, length and content-type" do get "/jimmy/tasks/" last_response.status.must_equal 200 @@ -28,9 +28,11 @@ describe "Directories" do foo = data_bucket.get("jimmy:tasks:foo") content = JSON.parse(last_response.body) - content.must_include "http://5apps.com" - content.must_include "foo" - content["foo"].must_equal foo.etag.gsub(/"/, "") + content["items"]["http://5apps.com"].wont_be_nil + content["items"]["foo"].wont_be_nil + content["items"]["foo"]["ETag"].must_equal foo.etag.gsub(/"/, "") + content["items"]["foo"]["Content-Type"].must_equal "text/plain" + content["items"]["foo"]["Content-Length"].must_equal 14 end it "has a Last-Modifier header set" do @@ -115,10 +117,10 @@ describe "Directories" do home = directory_bucket.get("jimmy:tasks/home") content = JSON.parse(last_response.body) - content.must_include "foo" - content.must_include "http://5apps.com" - content.must_include "home/" - content["home/"].must_equal home.etag.gsub(/"/, "") + content["items"]["foo"].wont_be_nil + content["items"]["http://5apps.com"].wont_be_nil + content["items"]["home/"].wont_be_nil + content["items"]["home/"]["ETag"].must_equal home.etag.gsub(/"/, "") end it "updates the ETag of the parent directory" do @@ -145,10 +147,10 @@ describe "Directories" do last_response.status.must_equal 200 content = JSON.parse(last_response.body) - content.wont_include "/" - content.wont_include "tasks/" - content.wont_include "home/" - content.must_include "homework" + content["items"]["/"].must_be_nil + content["items"]["tasks/"].must_be_nil + content["items"]["home/"].must_be_nil + content["items"]["homework"].wont_be_nil end end @@ -162,8 +164,7 @@ describe "Directories" do projects = directory_bucket.get("jimmy:tasks/private/projects") content = JSON.parse(last_response.body) - content.must_include "projects/" - content["projects/"].must_equal projects.etag.gsub(/"/, "") + content["items"]["projects/"]["ETag"].must_equal projects.etag.gsub(/"/, "") end it "updates the timestamps of the existing directory objects" do @@ -198,8 +199,9 @@ describe "Directories" do jaypeg = data_bucket.get("jimmy:tasks:jaypeg.jpg") content = JSON.parse(last_response.body) - content.must_include "jaypeg.jpg" - content["jaypeg.jpg"].must_equal jaypeg.etag.gsub(/"/, "") + content["items"]["jaypeg.jpg"]["ETag"].must_equal jaypeg.etag.gsub(/"/, "") + content["items"]["jaypeg.jpg"]["Content-Type"].must_equal "image/jpeg" + content["items"]["jaypeg.jpg"]["Content-Length"].must_equal 16044 end end @@ -219,8 +221,9 @@ describe "Directories" do jaypeg = data_bucket.get("jimmy:tasks:jaypeg.jpg") content = JSON.parse(last_response.body) - content.must_include "jaypeg.jpg" - content["jaypeg.jpg"].must_equal jaypeg.etag.gsub(/"/, "") + content["items"]["jaypeg.jpg"]["ETag"].must_equal jaypeg.etag.gsub(/"/, "") + content["items"]["jaypeg.jpg"]["Content-Type"].must_equal "image/jpeg" + content["items"]["jaypeg.jpg"]["Content-Length"].must_equal 16044 end end end @@ -239,8 +242,7 @@ describe "Directories" do laundry = data_bucket.get("jimmy:tasks/home:laundry") content = JSON.parse(last_response.body) - content.must_include "laundry" - content["laundry"].must_equal laundry.etag.gsub(/"/, "") + content["items"]["laundry"]["ETag"].must_equal laundry.etag.gsub(/"/, "") end end @@ -263,7 +265,7 @@ describe "Directories" do last_response.status.must_equal 200 content = JSON.parse(last_response.body) - content.must_include "foo~bar/" + content["items"]["foo~bar/"].wont_be_nil end it "lists the containing objects" do @@ -272,7 +274,7 @@ describe "Directories" do last_response.status.must_equal 200 content = JSON.parse(last_response.body) - content.must_include "task1" + content["items"]["task1"].wont_be_nil end it "returns the requested object" do @@ -295,7 +297,7 @@ describe "Directories" do last_response.status.must_equal 200 content = JSON.parse(last_response.body) - content.must_include "bla~blub" + content["items"]["bla~blub"].wont_be_nil end end @@ -317,10 +319,10 @@ describe "Directories" do tasks = directory_bucket.get("jimmy:tasks") content = JSON.parse(last_response.body) - content.must_include "root-1" - content.must_include "root-2" - content.must_include "tasks/" - content["tasks/"].must_equal tasks.etag.gsub(/"/, "") + content["items"]["root-1"].wont_be_nil + content["items"]["root-2"].wont_be_nil + content["items"]["tasks/"].wont_be_nil + content["items"]["tasks/"]["ETag"].must_equal tasks.etag.gsub(/"/, "") end it "has an ETag header set" do @@ -347,7 +349,7 @@ describe "Directories" do last_response.status.must_equal 200 content = JSON.parse(last_response.body) - content.must_include "5apps" + content["items"]["5apps"].wont_be_nil end it "has an ETag header set" do @@ -371,7 +373,7 @@ describe "Directories" do last_response.status.must_equal 200 content = JSON.parse(last_response.body) - content.must_include "5apps" + content["items"]["5apps"].wont_be_nil end end