google_drive 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.rdoc ADDED
@@ -0,0 +1,89 @@
1
+ This is a Ruby 1.8/1.9 library to read/write files/spreadsheets in Google Drive/Docs.
2
+
3
+
4
+ = How to install
5
+
6
+ $ sudo gem install google_drive
7
+
8
+
9
+ = How to use
10
+
11
+ Example to read/write files in Google Drive:
12
+
13
+ require "rubygems"
14
+ require "google_drive"
15
+
16
+ # Logs in.
17
+ # You can also use OAuth. See document of
18
+ # GoogleDrive.login_with_oauth for details.
19
+ session = GoogleDrive.login("username@gmail.com", "mypassword")
20
+
21
+ # Gets list of remote files.
22
+ for file in session.files
23
+ p file.title
24
+ end
25
+
26
+ # Uploads a local file.
27
+ session.upload_from_file("/path/to/hello.txt", "hello.txt", :convert => false)
28
+
29
+ # Downloads to a local file.
30
+ file = session.file_by_title("hello.txt")
31
+ file.download_to_file("/path/to/hello.txt")
32
+
33
+ # Updates content of the remote file.
34
+ file.update_from_file("/path/to/hello.txt")
35
+
36
+ Example to read/write spreadsheets:
37
+
38
+ require "rubygems"
39
+ require "google_drive"
40
+
41
+ # Logs in.
42
+ # You can also use OAuth. See document of
43
+ # GoogleDrive.login_with_oauth for details.
44
+ session = GoogleDrive.login("username@gmail.com", "mypassword")
45
+
46
+ # First worksheet of
47
+ # https://docs.google.com/spreadsheet/ccc?key=pz7XtlQC-PYx-jrVMJErTcg
48
+ ws = session.spreadsheet_by_key("pz7XtlQC-PYx-jrVMJErTcg").worksheets[0]
49
+
50
+ # Gets content of A2 cell.
51
+ p ws[2, 1] #==> "hoge"
52
+
53
+ # Changes content of cells.
54
+ # Changes are not sent to the server until you call ws.save().
55
+ ws[2, 1] = "foo"
56
+ ws[2, 2] = "bar"
57
+ ws.save()
58
+
59
+ # Dumps all cells.
60
+ for row in 1..ws.num_rows
61
+ for col in 1..ws.num_cols
62
+ p ws[row, col]
63
+ end
64
+ end
65
+
66
+ # Yet another way to do so.
67
+ p ws.rows #==> [["fuga", ""], ["foo", "bar]]
68
+
69
+ # Reloads the worksheet to get changes by other clients.
70
+ ws.reload()
71
+
72
+ API document: http://gimite.net/doc/google-drive-ruby/
73
+
74
+
75
+ = Source code
76
+
77
+ http://github.com/gimite/google-drive-ruby
78
+
79
+ The license of this source is "New BSD Licence"
80
+
81
+
82
+ = Supported environments
83
+
84
+ Ruby 1.8.x and Ruby 1.9.x. Checked with Ruby 1.8.7 and Ruby 1.9.3.
85
+
86
+
87
+ = Author
88
+
89
+ Hiroshi Ichikawa - http://gimite.net/en/index.php?Contact
@@ -0,0 +1,20 @@
1
+ module GoogleDrive
2
+
3
+ class Acl
4
+
5
+ # Returns the number of entries.
6
+ def size
7
+ end
8
+
9
+ # Returns GoogleDrive::AclEntry object at +index+.
10
+ def [](index)
11
+ end
12
+
13
+ # Iterates over GoogleDrive::AclEntry objects.
14
+ def each(&block)
15
+ yield(entry)
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,33 @@
1
+ module GoogleDrive
2
+
3
+ class AclEntry
4
+
5
+ # Type of the scope. One of:
6
+ #
7
+ # - "user": scope is a user's email address.
8
+ # - "group": scope is a Google Group email address.
9
+ # - "domain": scope is a Google Apps domain.
10
+ # - "default": Publicly shared with all users. scope is +nil+.
11
+ attr_reader(:scope_type)
12
+
13
+ # The scope. See scope_type.
14
+ attr_reader(:scope)
15
+
16
+ # The role given to the scope. One of:
17
+ # - "owner": The owner.
18
+ # - "writer": With read/write access.
19
+ # - "reader": With read-only access.
20
+ attr_reader(:role)
21
+
22
+ # Title of the entry.
23
+ attr_reader(:title)
24
+
25
+ # Edit URL of the entry.
26
+ attr_reader(:edit_url)
27
+
28
+ # E-tag of the entry.
29
+ attr_reader(:etag)
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,120 @@
1
+ # Author: Hiroshi Ichikawa <http://gimite.net/>
2
+ # The license of this source is "New BSD Licence"
3
+
4
+ require "google_drive/session"
5
+
6
+
7
+ module GoogleDrive
8
+
9
+ # Authenticates with given +mail+ and +password+, and returns GoogleDrive::Session
10
+ # if succeeds. Raises GoogleDrive::AuthenticationError if fails.
11
+ # Google Apps account is supported.
12
+ #
13
+ # +proxy+ can be nil or return value of Net::HTTP.Proxy. If +proxy+ is specified, all
14
+ # HTTP access in the session uses the proxy. If +proxy+ is nil, it uses the proxy
15
+ # specified by http_proxy environment variable if available. Otherwise it performs direct
16
+ # access.
17
+ def self.login(mail, password, proxy = nil)
18
+ return Session.login(mail, password, proxy)
19
+ end
20
+
21
+ # Authenticates with given OAuth1 or OAuth2 token.
22
+ #
23
+ # OAuth2 code example:
24
+ #
25
+ # client = OAuth2::Client.new(
26
+ # your_client_id, your_client_secret,
27
+ # :site => "https://accounts.google.com",
28
+ # :token_url => "/o/oauth2/token",
29
+ # :authorize_url => "/o/oauth2/auth")
30
+ # auth_url = client.auth_code.authorize_url(
31
+ # :redirect_uri => "http://example.com/",
32
+ # "scope" => "https://spreadsheets.google.com/feeds https://docs.google.com/feeds/")
33
+ # # Redirect the user to auth_url and get authorization code from redirect URL.
34
+ # auth_token = client.auth_code.get_token(
35
+ # authorization_code, :redirect_uri => "http://example.com/")
36
+ # session = GoogleDrive.login_with_oauth(auth_token)
37
+ #
38
+ # Or, from existing refresh token:
39
+ #
40
+ # access_token = OAuth2::AccessToken.from_hash(client,
41
+ # {:refresh_token => refresh_token, :expires_at => expires_at})
42
+ # access_token = access_token.refresh!
43
+ # session = GoogleDrive.login_with_oauth(access_token)
44
+ #
45
+ # OAuth1 code example:
46
+ #
47
+ # 1) First generate OAuth consumer object with key and secret for your site by registering site
48
+ # with Google.
49
+ # @consumer = OAuth::Consumer.new( "key","secret", {:site=>"https://agree2"})
50
+ # 2) Request token with OAuth.
51
+ # @request_token = @consumer.get_request_token
52
+ # session[:request_token] = @request_token
53
+ # redirect_to @request_token.authorize_url
54
+ # 3) Create an oauth access token.
55
+ # @oauth_access_token = @request_token.get_access_token
56
+ # @access_token = OAuth::AccessToken.new(
57
+ # @consumer, @oauth_access_token.token, @oauth_access_token.secret)
58
+ #
59
+ # See these documents for details:
60
+ #
61
+ # - https://github.com/intridea/oauth2
62
+ # - http://code.google.com/apis/accounts/docs/OAuth2.html
63
+ # - http://oauth.rubyforge.org/
64
+ # - http://code.google.com/apis/accounts/docs/OAuth.html
65
+ def self.login_with_oauth(oauth_token)
66
+ return Session.login_with_oauth(oauth_token)
67
+ end
68
+
69
+ # Restores session using return value of auth_tokens method of previous session.
70
+ #
71
+ # See GoogleDrive.login for description of parameter +proxy+.
72
+ def self.restore_session(auth_tokens, proxy = nil)
73
+ return Session.restore_session(auth_tokens, proxy)
74
+ end
75
+
76
+ # Restores GoogleDrive::Session from +path+ and returns it.
77
+ # If +path+ doesn't exist or authentication has failed, prompts mail and password on console,
78
+ # authenticates with them, stores the session to +path+ and returns it.
79
+ #
80
+ # See login for description of parameter +proxy+.
81
+ #
82
+ # This method requires Highline library: http://rubyforge.org/projects/highline/
83
+ def self.saved_session(path = ENV["HOME"] + "/.ruby_google_drive.token", proxy = nil)
84
+ tokens = {}
85
+ if ::File.exist?(path)
86
+ open(path) do |f|
87
+ for auth in [:wise, :writely]
88
+ line = f.gets()
89
+ tokens[auth] = line && line.chomp()
90
+ end
91
+ end
92
+ end
93
+ session = Session.new(tokens, nil, proxy)
94
+ session.on_auth_fail = proc() do
95
+ begin
96
+ require "highline"
97
+ rescue LoadError
98
+ raise(LoadError,
99
+ "GoogleDrive.saved_session requires Highline library.\n" +
100
+ "Run\n" +
101
+ " \$ sudo gem install highline\n" +
102
+ "to install it.")
103
+ end
104
+ highline = HighLine.new()
105
+ mail = highline.ask("Mail: ")
106
+ password = highline.ask("Password: "){ |q| q.echo = false }
107
+ session.login(mail, password)
108
+ open(path, "w", 0600) do |f|
109
+ f.puts(session.auth_token(:wise))
110
+ f.puts(session.auth_token(:writely))
111
+ end
112
+ true
113
+ end
114
+ if !session.auth_token
115
+ session.on_auth_fail.call()
116
+ end
117
+ return session
118
+ end
119
+
120
+ end
@@ -0,0 +1,124 @@
1
+ # Author: Guy Boertje <https://github.com/guyboertje>
2
+ # Author: David R. Albrecht <https://github.com/eldavido>
3
+ # Author: Hiroshi Ichikawa <http://gimite.net/>
4
+ # The license of this source is "New BSD Licence"
5
+
6
+ require "google_drive/acl_entry"
7
+
8
+
9
+ module GoogleDrive
10
+
11
+ # ACL (access control list) of a spreadsheet.
12
+ #
13
+ # Use GoogleDrive::Spreadsheet#acl to get GoogleDrive::Acl object.
14
+ # See GoogleDrive::Spreadsheet#acl for usage example.
15
+ #
16
+ # This code is based on https://github.com/guyboertje/gdata-spreadsheet-ruby .
17
+ class Acl
18
+
19
+ include(Util)
20
+ extend(Forwardable)
21
+
22
+ def initialize(session, acls_feed_url) #:nodoc:
23
+ @session = session
24
+ @acls_feed_url = acls_feed_url
25
+ header = {"GData-Version" => "3.0"}
26
+ doc = @session.request(:get, @acls_feed_url, :header => header, :auth => :writely)
27
+ @acls = doc.css("entry").map(){ |e| AclEntry.new(entry_to_params(e)) }
28
+ end
29
+
30
+ def_delegators(:@acls, :size, :[], :each)
31
+
32
+ # Adds a new entry. +entry+ is either a GoogleDrive::AclEntry or a Hash with keys
33
+ # :scope_type, :scope and :role. See GoogleDrive::AclEntry#scope_type and
34
+ # GoogleDrive::AclEntry#role for the document of the fields.
35
+ #
36
+ # NOTE: This sends email to the new people.
37
+ #
38
+ # e.g.
39
+ # spreadsheet.acl.push(
40
+ # {:scope_type => "user", :scope => "example2@gmail.com", :role => "reader"})
41
+ # spreadsheet.acl.push(
42
+ # {:scope_type => "user", :scope => "example3@gmail.com", :role => "writer"})
43
+ def push(entry)
44
+
45
+ entry = AclEntry.new(entry) if entry.is_a?(Hash)
46
+
47
+ header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
48
+ value_attr = entry.scope ? "value='#{h(entry.scope)}'" : ""
49
+ xml = <<-EOS
50
+ <entry
51
+ xmlns='http://www.w3.org/2005/Atom'
52
+ xmlns:gAcl='http://schemas.google.com/acl/2007'>
53
+ <category scheme='http://schemas.google.com/g/2005#kind'
54
+ term='http://schemas.google.com/acl/2007#accessRule'/>
55
+ <gAcl:role value='#{h(entry.role)}'/>
56
+ <gAcl:scope type='#{h(entry.scope_type)}' #{value_attr}/>
57
+ </entry>
58
+ EOS
59
+ doc = @session.request(
60
+ :post, @acls_feed_url, :data => xml, :header => header, :auth => :writely)
61
+
62
+ entry.params = entry_to_params(doc.root)
63
+ @acls.push(entry)
64
+ return entry
65
+
66
+ end
67
+
68
+ # Deletes an ACL entry.
69
+ #
70
+ # e.g.
71
+ # spreadsheet.acl.delete(spreadsheet.acl[1])
72
+ def delete(entry)
73
+ header = {"GData-Version" => "3.0"}
74
+ @session.request(:delete, entry.edit_url, :header => header, :auth => :writely)
75
+ @acls.delete(entry)
76
+ end
77
+
78
+ def update_role(entry, role) #:nodoc:
79
+
80
+ header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
81
+ value_attr = entry.scope ? "value='#{h(entry.scope)}'" : ""
82
+ xml = <<-EOS
83
+ <entry
84
+ xmlns='http://www.w3.org/2005/Atom'
85
+ xmlns:gAcl='http://schemas.google.com/acl/2007'
86
+ xmlns:gd='http://schemas.google.com/g/2005'
87
+ gd:etag='#{h(entry.etag)}'>
88
+ <category
89
+ scheme='http://schemas.google.com/g/2005#kind'
90
+ term='http://schemas.google.com/acl/2007#accessRule'/>
91
+ <gAcl:role value='#{h(role)}'/>
92
+ <gAcl:scope type='#{h(entry.scope_type)}' #{value_attr}/>
93
+ </entry>
94
+ EOS
95
+ doc = @session.request(
96
+ :put, entry.edit_url, :data => xml, :header => header, :auth => :writely)
97
+
98
+ entry.params = entry_to_params(doc.root)
99
+ return entry
100
+
101
+ end
102
+
103
+ def inspect
104
+ return "\#<%p %p>" % [self.class, @acls]
105
+ end
106
+
107
+ private
108
+
109
+ def entry_to_params(entry)
110
+ # TODO Support with-link roles.
111
+ return {
112
+ :acl => self,
113
+ :scope_type => entry.css("gAcl|scope")[0]["type"],
114
+ :scope => entry.css("gAcl|scope")[0]["value"],
115
+ :role => entry.css("gAcl|role")[0]["value"],
116
+ :title => entry.css("title").text,
117
+ :edit_url => entry.css("link[rel='edit']")[0]["href"],
118
+ :etag => entry["etag"],
119
+ }
120
+ end
121
+
122
+ end
123
+
124
+ end
@@ -0,0 +1,58 @@
1
+ # Author: Guy Boertje <https://github.com/guyboertje>
2
+ # Author: David R. Albrecht <https://github.com/eldavido>
3
+ # Author: Hiroshi Ichikawa <http://gimite.net/>
4
+ # The license of this source is "New BSD Licence"
5
+
6
+ # acl.rb, derived from https://github.com/guyboertje/gdata-spreadsheet-ruby/blob/master/lib/document.rb
7
+ # more frankensteining of the original library
8
+
9
+ module GoogleDrive
10
+
11
+ # An entry of an ACL (access control list) of a spreadsheet.
12
+ #
13
+ # Use GoogleDrive::Acl#[] to get GoogleDrive::AclEntry object.
14
+ #
15
+ # This code is based on https://github.com/guyboertje/gdata-spreadsheet-ruby .
16
+ class AclEntry
17
+
18
+ include(Util)
19
+
20
+ PARAM_NAMES = [:acl, :scope_type, :scope, :role, :title, :edit_url, :etag] #:nodoc:
21
+
22
+ # +params+ is a Hash object with keys +:scope_type+, +:scope+ and +:role+.
23
+ # See scope_type and role for the document of the fields.
24
+ def initialize(params)
25
+ @params = {:role => "reader"}
26
+ for name, value in params
27
+ if !PARAM_NAMES.include?(name)
28
+ raise(ArgumentError, "Invalid key: %p" % name)
29
+ end
30
+ @params[name] = value
31
+ end
32
+ end
33
+
34
+ attr_accessor(:params) #:nodoc:
35
+
36
+ PARAM_NAMES.each() do |name|
37
+ define_method(name) do
38
+ return @params[name]
39
+ end
40
+ end
41
+
42
+ # Changes the role of the scope.
43
+ #
44
+ # e.g.
45
+ # spreadsheet.acl[1].role = "writer"
46
+ def role=(role)
47
+ @params[:acl].update_role(self, role)
48
+ end
49
+
50
+ def inspect
51
+ return "\#<%p scope_type=%p, scope=%p, role=%p>" %
52
+ [self.class, @params[:scope_type], @params[:scope], @params[:role]]
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+