Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(storage): fetch file and bucket details from url #27322

Merged
44 changes: 44 additions & 0 deletions google-cloud-storage/lib/google/cloud/storage/file.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2081,6 +2081,50 @@ def self.gapi_from_attrs gapi, attributes
Google::Apis::StorageV1::Object.new(**attr_params)
end

##
# from_gs_url is a method to fetch bucket details and file details from a gs url
#
# @return [Hash(String => String)]
#
# @example Fetch bucket_name and file_Path from gs url:
# require "google/cloud/storage"
# gs_url= "gs://my-todo-app/avatars/heidi.jpeg"
# file=Google::Cloud::Storage::File
# file.from_gs_url(gs_url)
# =>
# {"bucket_name"=>"my-todo-app", "file_path"=>"avatars/heidi.jpeg"}
#
# @example Fetch bucket_name , file_Path and other query params from gs url:
# require "google/cloud/storage"
# gs_url= "gs://my-todo-app/test_sub_folder/heidi.jpeg?params1=test1&params2=test2"
# file=Google::Cloud::Storage::File
# file.from_gs_url(gs_url)
# =>{
# "bucket_name"=>"my-todo-app",
# "file_path"=>"test_sub_folder/heidi.jpeg",
# "options" => {
# "params1"=>"test1",
# "params2"=>"test2"
# }
# }

def self.from_gs_url gs_url
prefix = "gs://".freeze
raise ArgumentError, "Invalid GCS URL" unless gs_url.start_with? prefix
# seprating params from input url
path, query = gs_url.sub(prefix, "").split("?", 2)
# parsing the url
bucket_name, file_path = path.split "/", 2
query_params = URI.decode_www_form(query).to_h if query
url_items = {
"bucket_name" => bucket_name,
"file_path" => file_path
}
# adding url params to output hash
url_items.merge! "options" => query_params if query
url_items
end

protected

##
Expand Down
39 changes: 39 additions & 0 deletions google-cloud-storage/test/google/cloud/storage/file_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1571,6 +1571,45 @@ def file_user_project.sleep *args
end
end

describe "fetch details from gs_url" do
shubhangi-google marked this conversation as resolved.
Show resolved Hide resolved
let(:bucket_name) { "my-random-bucket" }
let(:file_path) {"file.jpeg"}
let(:file) {Google::Cloud::Storage::File}
let(:param) {"param1"}
let(:param_val) {"test"}
let(:gs_url) {"gs://#{bucket_name}/#{file_path}"}

it "it returns file_name and bucket_name from given gs url" do
url_items = file.from_gs_url gs_url
assert_equal bucket_name, url_items["bucket_name"]
assert_equal file_path, url_items["file_path"]
end

it "it returns file_name, bucket_name and url params in options hash from given gs url with parameters" do
gs_url= "gs://#{bucket_name}/#{file_path}?#{param}=#{param_val}"
url_items = file.from_gs_url gs_url
assert_equal bucket_name, url_items["bucket_name"]
assert_equal file_path, url_items["file_path"]
expected_params_hash_in_output = {'param1' =>'test'}
assert_equal expected_params_hash_in_output, url_items["options"]
end

it "it returns file_path with subfolder name and file name and bucket_name from given gs url" do
file_path = "avatars/#{file_path}"
gs_url = "gs://#{bucket_name}/#{file_path}"
url_items = file.from_gs_url gs_url
assert_equal bucket_name, url_items["bucket_name"]
assert_equal file_path, url_items["file_path"]
end

it "raises error if url provided is not a valid gs url" do
invalid_gs_url = "http://my_bucket/my_file.txt"
assert_raises ArgumentError do
file.from_gs_url invalid_gs_url
end
end
end

def gzip_data data
gz = StringIO.new("")
z = Zlib::GzipWriter.new(gz)
Expand Down
Loading