Skip to content

Commit

Permalink
feat(storage): fetch file and bucket details from url (#27322)
Browse files Browse the repository at this point in the history
  • Loading branch information
shubhangi-google committed Sep 21, 2024
1 parent 5ad3072 commit 805ca25
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 0 deletions.
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
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

0 comments on commit 805ca25

Please sign in to comment.