Skip to content

Commit 805ca25

Browse files
feat(storage): fetch file and bucket details from url (#27322)
1 parent 5ad3072 commit 805ca25

2 files changed

Lines changed: 83 additions & 0 deletions

File tree

google-cloud-storage/lib/google/cloud/storage/file.rb

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2081,6 +2081,50 @@ def self.gapi_from_attrs gapi, attributes
20812081
Google::Apis::StorageV1::Object.new(**attr_params)
20822082
end
20832083

2084+
##
2085+
# from_gs_url is a method to fetch bucket details and file details from a gs url
2086+
#
2087+
# @return [Hash(String => String)]
2088+
#
2089+
# @example Fetch bucket_name and file_Path from gs url:
2090+
# require "google/cloud/storage"
2091+
# gs_url= "gs://my-todo-app/avatars/heidi.jpeg"
2092+
# file=Google::Cloud::Storage::File
2093+
# file.from_gs_url(gs_url)
2094+
# =>
2095+
# {"bucket_name"=>"my-todo-app", "file_path"=>"avatars/heidi.jpeg"}
2096+
#
2097+
# @example Fetch bucket_name , file_Path and other query params from gs url:
2098+
# require "google/cloud/storage"
2099+
# gs_url= "gs://my-todo-app/test_sub_folder/heidi.jpeg?params1=test1&params2=test2"
2100+
# file=Google::Cloud::Storage::File
2101+
# file.from_gs_url(gs_url)
2102+
# =>{
2103+
# "bucket_name"=>"my-todo-app",
2104+
# "file_path"=>"test_sub_folder/heidi.jpeg",
2105+
# "options" => {
2106+
# "params1"=>"test1",
2107+
# "params2"=>"test2"
2108+
# }
2109+
# }
2110+
2111+
def self.from_gs_url gs_url
2112+
prefix = "gs://".freeze
2113+
raise ArgumentError, "Invalid GCS URL" unless gs_url.start_with? prefix
2114+
# seprating params from input url
2115+
path, query = gs_url.sub(prefix, "").split("?", 2)
2116+
# parsing the url
2117+
bucket_name, file_path = path.split "/", 2
2118+
query_params = URI.decode_www_form(query).to_h if query
2119+
url_items = {
2120+
"bucket_name" => bucket_name,
2121+
"file_path" => file_path
2122+
}
2123+
# adding url params to output hash
2124+
url_items.merge! "options" => query_params if query
2125+
url_items
2126+
end
2127+
20842128
protected
20852129

20862130
##

google-cloud-storage/test/google/cloud/storage/file_test.rb

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,45 @@ def file_user_project.sleep *args
15711571
end
15721572
end
15731573

1574+
describe "fetch details from gs_url" do
1575+
let(:bucket_name) { "my-random-bucket" }
1576+
let(:file_path) {"file.jpeg"}
1577+
let(:file) {Google::Cloud::Storage::File}
1578+
let(:param) {"param1"}
1579+
let(:param_val) {"test"}
1580+
let(:gs_url) {"gs://#{bucket_name}/#{file_path}"}
1581+
1582+
it "it returns file_name and bucket_name from given gs url" do
1583+
url_items = file.from_gs_url gs_url
1584+
assert_equal bucket_name, url_items["bucket_name"]
1585+
assert_equal file_path, url_items["file_path"]
1586+
end
1587+
1588+
it "it returns file_name, bucket_name and url params in options hash from given gs url with parameters" do
1589+
gs_url= "gs://#{bucket_name}/#{file_path}?#{param}=#{param_val}"
1590+
url_items = file.from_gs_url gs_url
1591+
assert_equal bucket_name, url_items["bucket_name"]
1592+
assert_equal file_path, url_items["file_path"]
1593+
expected_params_hash_in_output = {'param1' =>'test'}
1594+
assert_equal expected_params_hash_in_output, url_items["options"]
1595+
end
1596+
1597+
it "it returns file_path with subfolder name and file name and bucket_name from given gs url" do
1598+
file_path = "avatars/#{file_path}"
1599+
gs_url = "gs://#{bucket_name}/#{file_path}"
1600+
url_items = file.from_gs_url gs_url
1601+
assert_equal bucket_name, url_items["bucket_name"]
1602+
assert_equal file_path, url_items["file_path"]
1603+
end
1604+
1605+
it "raises error if url provided is not a valid gs url" do
1606+
invalid_gs_url = "http://my_bucket/my_file.txt"
1607+
assert_raises ArgumentError do
1608+
file.from_gs_url invalid_gs_url
1609+
end
1610+
end
1611+
end
1612+
15741613
def gzip_data data
15751614
gz = StringIO.new("")
15761615
z = Zlib::GzipWriter.new(gz)

0 commit comments

Comments
 (0)