gstore 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) Richard Taylor
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,53 @@
1
+ h1. Ruby client library for the Google Storage API
2
+
3
+ This is the first release and supports all the basic operations. Advanced support for ACLs etc.. coming soon
4
+
5
+ h2. Install the gem
6
+
7
+ sudo gem install gstore
8
+
9
+ h2. Using the gem
10
+
11
+ Visit "The Google Storage Key Manager":https://sandbox.google.com/storage/m/manage to get your access and secret keys.
12
+
13
+ In your code just: <code>require 'gstore'</code>
14
+
15
+ h2. Example
16
+
17
+ Create an instance of the client with your credentials:
18
+
19
+ <pre><code>client = GStore::Client.new(
20
+ :access_key => 'YOUR_ACCESS_KEY',
21
+ :secret_key => 'YOUR_SECRET_KEY'
22
+ )
23
+
24
+ # List all of your existing Buckets
25
+ client.list_buckets
26
+ </code></pre>
27
+
28
+ Here are some example bucket operations:
29
+
30
+ <pre><code># Create a Bucket
31
+ client.create_bucket('my_unique_bucket')
32
+
33
+ # Retrieve a Bucket
34
+ client.get_bucket('my_unique_bucket')
35
+
36
+ # Delete a [empty] Bucket
37
+ client.delete_bucket('my_unique_bucket')
38
+ </code></pre>
39
+
40
+ Once you have a bucket you can manipulate objects in the following way:
41
+
42
+ <pre><code># Store a file in a bucket
43
+ client.put_object('my_unique_bucket', 'my_first_object', :data => File.read('mytext.txt'))
44
+
45
+ # Retrieve the contents of the object in the specified bucket
46
+ puts client.get_object('my_unique_bucket', 'my_first_object')
47
+
48
+ # Alternatively specify an outfile and the contents will be saved to there
49
+ client.get_object('my_unique_bucket', 'my_first_object', :outfile => 'retrieved_mytext.txt')
50
+
51
+ # Delete an object from the bucket
52
+ client.delete_object('my_unique_bucket', 'my_first_object')
53
+ </code></pre>
@@ -0,0 +1,5 @@
1
+ require 'gstore/client'
2
+
3
+ module GStore
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,21 @@
1
+ module GStore
2
+ class Client
3
+
4
+ def list_buckets(options={})
5
+ get(nil, '/', options)
6
+ end
7
+
8
+ def create_bucket(bucket, options={})
9
+ put(bucket, '/', options)
10
+ end
11
+
12
+ def get_bucket(bucket, options={})
13
+ get(bucket, '/', options)
14
+ end
15
+
16
+ def delete_bucket(bucket, options={})
17
+ delete(bucket, '/', options)
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,41 @@
1
+ require 'gstore/request'
2
+ require 'gstore/bucket'
3
+ require 'gstore/object'
4
+
5
+ module GStore
6
+ class Client
7
+
8
+ def initialize(options = {})
9
+ @access_key = options[:access_key]
10
+ @secret_key = options[:secret_key]
11
+ @debug = options[:debug] and options[:debug] == true
12
+ @host = options[:host] || 'commondatastorage.googleapis.com'
13
+ end
14
+
15
+ private
16
+
17
+ def get(bucket, path, params={}, options={})
18
+ _http_request(Net::HTTP::Get, bucket, path, params, options)
19
+ end
20
+
21
+ def put(bucket, path, params={}, options={})
22
+ _http_request(Net::HTTP::Put, bucket, path, params, options)
23
+ end
24
+
25
+ def delete(bucket, path, params={}, options={})
26
+ _http_request(Net::HTTP::Delete, bucket, path, params, options)
27
+ end
28
+
29
+ def head(bucket, path, params={}, options={})
30
+ _http_request(Net::HTTP::Head, bucket, path, params, options)
31
+ end
32
+
33
+ def _http_request(method, bucket, path, params, options={})
34
+ host = @host
35
+ host = "#{bucket}.#{@host}" if bucket
36
+ signed_request(method, host, path, params, options)
37
+ end
38
+
39
+ end
40
+ end
41
+
@@ -0,0 +1,25 @@
1
+ module GStore
2
+ class Client
3
+ def put_object(bucket, filename, data, options={})
4
+ put(bucket, "/#{filename}", options, data)
5
+ end
6
+
7
+ def get_object(bucket, filename, options={})
8
+ outfile = options.delete(:outfile)
9
+ res = get(bucket, "/#{filename}", options)
10
+ if outfile
11
+ File.open(outfile, 'w') {|f| f.write(res) }
12
+ else
13
+ res
14
+ end
15
+ end
16
+
17
+ def delete_object(bucket, filename, options={})
18
+ delete(bucket, "/#{filename}", options)
19
+ end
20
+
21
+ def get_object_metadata(bucket, filename, options={})
22
+ head(bucket, "/#{filename}", options)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,98 @@
1
+ require 'time'
2
+ require 'openssl'
3
+ require 'digest/sha1'
4
+ require 'base64'
5
+ require 'uri'
6
+ require 'net/https'
7
+ require 'cgi'
8
+
9
+ module GStore
10
+ class Client
11
+
12
+ def signed_request(method, host, path, params={}, options={})
13
+
14
+ if @debug
15
+ puts
16
+ puts "***** METHOD: #{method}"
17
+ puts "***** HOST: #{host}"
18
+ puts "***** PATH: #{path}"
19
+ puts "***** PARAMS: #{params.inspect}"
20
+ puts "***** OPTIONS: #{options.inspect}"
21
+ puts
22
+ end
23
+
24
+ headers = {
25
+ :Host => host,
26
+ :Date => Time.now.utc.strftime('%a, %d %b %Y %H:%M:%S -0000'),
27
+ :"Content-Type" => 'text/plain',
28
+ #:"Content-MD5" => ''
29
+ }
30
+ if options[:data]
31
+ headers = headers.merge(:"Content-Length" => options[:data].size)
32
+ else
33
+ headers = headers.merge(:"Content-Length" => 0)
34
+ end
35
+
36
+ bucket = nil
37
+ if host =~ /(\S+).#{@host}/
38
+ bucket = $1
39
+ end
40
+
41
+ canonical_headers = method.name.gsub('Net::HTTP::', '').upcase + "\n" +
42
+ '' + "\n" + # Content-MD5
43
+ headers[:"Content-Type"] + "\n" + # Content-Type
44
+ headers[:Date] + "\n" # Date
45
+
46
+ canonical_resource = ""
47
+ canonical_resource += "/#{bucket}" if bucket
48
+ canonical_resource += path
49
+
50
+ authorization = 'GOOG1 ' + @access_key + ':' + sign((canonical_headers + canonical_resource).toutf8)
51
+
52
+ if @debug
53
+ puts
54
+ puts "+++++ BUCKET: #{bucket}"
55
+ puts "+++++ HEADERS: #{headers.inspect}"
56
+ puts "+++++ CANONICAL_HEADERS: #{canonical_headers}"
57
+ puts "+++++ CANONICAL_RESOURCE: #{canonical_resource}"
58
+ puts "+++++ AUTHORIZATION: #{authorization}"
59
+ puts
60
+ end
61
+
62
+ _http_do(method, host, path, params_to_request_string(params), headers.merge(:Authorization => authorization), options[:data])
63
+ end
64
+
65
+ private
66
+ def sign(str)
67
+ digest = OpenSSL::Digest::Digest.new('sha1')
68
+ b64_hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, @secret_key, str)).gsub("\n","")
69
+ end
70
+
71
+ def _http_do(method, host, path, params, headers, data=nil)
72
+ http = Net::HTTP.new(host, 443)
73
+ http.use_ssl = true
74
+
75
+ http.start do
76
+ req = method.new(path)
77
+ req.content_type = 'application/x-www-form-urlencoded'
78
+ req['User-Agent'] = "moomerman-gstore-gem"
79
+ headers.each do |key, value|
80
+ req[key.to_s] = value
81
+ end
82
+
83
+ response = http.request(req, data)
84
+
85
+ return response.body
86
+ end
87
+ end
88
+
89
+ def params_to_request_string(params)
90
+ sorted_params = params.sort {|x,y| x[0].to_s <=> y[0].to_s}
91
+ escaped_params = sorted_params.collect do |p|
92
+ encoded = (CGI::escape(p[0].to_s) + "=" + CGI::escape(p[1].to_s))
93
+ encoded.gsub('+', '%20')
94
+ end
95
+ escaped_params.join('&')
96
+ end
97
+ end
98
+ end
metadata ADDED
@@ -0,0 +1,62 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gstore
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Richard Taylor
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-06-15 00:00:00 +01:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: gstore is a Ruby client library for the Google Storage API.
17
+ email: moomerman@gmail.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - LICENSE
26
+ - README.textile
27
+ - lib/gstore.rb
28
+ - lib/gstore/bucket.rb
29
+ - lib/gstore/client.rb
30
+ - lib/gstore/object.rb
31
+ - lib/gstore/request.rb
32
+ has_rdoc: true
33
+ homepage: http://github.com/moomerman/gstore
34
+ licenses: []
35
+
36
+ post_install_message:
37
+ rdoc_options:
38
+ - --inline-source
39
+ - --charset=UTF-8
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ required_rubygems_version: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: "0"
53
+ version:
54
+ requirements: []
55
+
56
+ rubyforge_project: gstore
57
+ rubygems_version: 1.3.5
58
+ signing_key:
59
+ specification_version: 2
60
+ summary: gstore is a Ruby client library for the Google Storage API.
61
+ test_files: []
62
+