Generate directory listing from Redis metadata
This commit is contained in:
		
							parent
							
								
									dfc8a59096
								
							
						
					
					
						commit
						599865cf3f
					
				@ -75,6 +75,48 @@ module RemoteStorage
 | 
				
			|||||||
    end
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_directory_listing(user, directory)
 | 
					    def get_directory_listing(user, directory)
 | 
				
			||||||
 | 
					      # TODO add ETag header
 | 
				
			||||||
 | 
					      # TODO check IF_NONE_MATCH header
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      server.headers["Content-Type"] = "application/json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      listing = {
 | 
				
			||||||
 | 
					        "@context" => "http://remotestorage.io/spec/folder-description",
 | 
				
			||||||
 | 
					        "items"    => {}
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      items = redis.smembers "rs_meta:#{user}:#{directory}/:items"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      items.sort.each do |name|
 | 
				
			||||||
 | 
					        redis_key = if directory.empty?
 | 
				
			||||||
 | 
					                      "rs_meta:phil:#{name}"
 | 
				
			||||||
 | 
					                    else
 | 
				
			||||||
 | 
					                      "rs_meta:phil:#{directory}/#{name}"
 | 
				
			||||||
 | 
					                    end
 | 
				
			||||||
 | 
					        metadata = redis.hgetall redis_key
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if name[-1] == "/" # It's a directory
 | 
				
			||||||
 | 
					          listing["items"].merge!({
 | 
				
			||||||
 | 
					            name => {
 | 
				
			||||||
 | 
					              "ETag" => metadata["etag"]
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          })
 | 
				
			||||||
 | 
					        else # It's a file
 | 
				
			||||||
 | 
					          listing["items"].merge!({
 | 
				
			||||||
 | 
					            name => {
 | 
				
			||||||
 | 
					              "ETag"           => metadata["etag"],
 | 
				
			||||||
 | 
					              "Content-Type"   => metadata["type"],
 | 
				
			||||||
 | 
					              "Content-Length" => metadata["size"].to_i
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      listing.to_json
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_directory_listing_from_swift(user, directory)
 | 
				
			||||||
      is_root_listing = directory.empty?
 | 
					      is_root_listing = directory.empty?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      server.headers["Content-Type"] = "application/json"
 | 
					      server.headers["Content-Type"] = "application/json"
 | 
				
			||||||
 | 
				
			|||||||
@ -148,5 +148,63 @@ describe "App" do
 | 
				
			|||||||
      end
 | 
					      end
 | 
				
			||||||
    end
 | 
					    end
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  describe "GET requests" do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    before do
 | 
				
			||||||
 | 
					      purge_redis
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    context "authorized" do
 | 
				
			||||||
 | 
					      before do
 | 
				
			||||||
 | 
					        redis.sadd "authorizations:phil:amarillo", [":rw"]
 | 
				
			||||||
 | 
					        header "Authorization", "Bearer amarillo"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        put_stub = OpenStruct.new(headers: {etag: "bla"})
 | 
				
			||||||
 | 
					        RemoteStorage::Swift.stub_any_instance :has_name_collision?, false do
 | 
				
			||||||
 | 
					          RestClient.stub :put, put_stub do
 | 
				
			||||||
 | 
					            put "/phil/food/aguacate", "si"
 | 
				
			||||||
 | 
					            put "/phil/food/camaron", "yummi"
 | 
				
			||||||
 | 
					            put "/phil/food/desunyos/bolon", "wow"
 | 
				
			||||||
 | 
					          end
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      describe "directory listings" do
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it "contains all items in the directory" do
 | 
				
			||||||
 | 
					          get "/phil/food/"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          last_response.status.must_equal 200
 | 
				
			||||||
 | 
					          last_response.content_type.must_equal "application/json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          content = JSON.parse(last_response.body)
 | 
				
			||||||
 | 
					          content["@context"].must_equal "http://remotestorage.io/spec/folder-description"
 | 
				
			||||||
 | 
					          content["items"]["aguacate"].wont_be_nil
 | 
				
			||||||
 | 
					          content["items"]["aguacate"]["Content-Type"].must_equal "text/plain; charset=utf-8"
 | 
				
			||||||
 | 
					          content["items"]["aguacate"]["Content-Length"].must_equal 2
 | 
				
			||||||
 | 
					          content["items"]["aguacate"]["ETag"].must_equal "bla"
 | 
				
			||||||
 | 
					          content["items"]["camaron"].wont_be_nil
 | 
				
			||||||
 | 
					          content["items"]["camaron"]["Content-Type"].must_equal "text/plain; charset=utf-8"
 | 
				
			||||||
 | 
					          content["items"]["camaron"]["Content-Length"].must_equal 5
 | 
				
			||||||
 | 
					          content["items"]["camaron"]["ETag"].must_equal "bla"
 | 
				
			||||||
 | 
					          content["items"]["desunyos/"].wont_be_nil
 | 
				
			||||||
 | 
					          content["items"]["desunyos/"]["ETag"].must_equal "bla"
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        it "contains all items in the root directory" do
 | 
				
			||||||
 | 
					          get "phil/"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          last_response.status.must_equal 200
 | 
				
			||||||
 | 
					          last_response.content_type.must_equal "application/json"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          content = JSON.parse(last_response.body)
 | 
				
			||||||
 | 
					          content["items"]["food/"].wont_be_nil
 | 
				
			||||||
 | 
					          content["items"]["food/"]["ETag"].must_equal "bla"
 | 
				
			||||||
 | 
					        end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      end
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user