parallel588_google_drive 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,91 @@
1
+ This is a Ruby 1.8/1.9 library to read/write files/spreadsheets in Google Drive/Docs.
2
+
3
+ NOTE: This is NOT a library to create Google Drive App.
4
+
5
+
6
+ = How to install
7
+
8
+ $ sudo gem install google_drive
9
+
10
+
11
+ = How to use
12
+
13
+ Example to read/write files in Google Drive:
14
+
15
+ require "rubygems"
16
+ require "google_drive"
17
+
18
+ # Logs in.
19
+ # You can also use OAuth. See document of
20
+ # GoogleDrive.login_with_oauth for details.
21
+ session = GoogleDrive.login("username@gmail.com", "mypassword")
22
+
23
+ # Gets list of remote files.
24
+ for file in session.files
25
+ p file.title
26
+ end
27
+
28
+ # Uploads a local file.
29
+ session.upload_from_file("/path/to/hello.txt", "hello.txt", :convert => false)
30
+
31
+ # Downloads to a local file.
32
+ file = session.file_by_title("hello.txt")
33
+ file.download_to_file("/path/to/hello.txt")
34
+
35
+ # Updates content of the remote file.
36
+ file.update_from_file("/path/to/hello.txt")
37
+
38
+ Example to read/write spreadsheets:
39
+
40
+ require "rubygems"
41
+ require "google_drive"
42
+
43
+ # Logs in.
44
+ # You can also use OAuth. See document of
45
+ # GoogleDrive.login_with_oauth for details.
46
+ session = GoogleDrive.login("username@gmail.com", "mypassword")
47
+
48
+ # First worksheet of
49
+ # https://docs.google.com/spreadsheet/ccc?key=pz7XtlQC-PYx-jrVMJErTcg
50
+ ws = session.spreadsheet_by_key("pz7XtlQC-PYx-jrVMJErTcg").worksheets[0]
51
+
52
+ # Gets content of A2 cell.
53
+ p ws[2, 1] #==> "hoge"
54
+
55
+ # Changes content of cells.
56
+ # Changes are not sent to the server until you call ws.save().
57
+ ws[2, 1] = "foo"
58
+ ws[2, 2] = "bar"
59
+ ws.save()
60
+
61
+ # Dumps all cells.
62
+ for row in 1..ws.num_rows
63
+ for col in 1..ws.num_cols
64
+ p ws[row, col]
65
+ end
66
+ end
67
+
68
+ # Yet another way to do so.
69
+ p ws.rows #==> [["fuga", ""], ["foo", "bar]]
70
+
71
+ # Reloads the worksheet to get changes by other clients.
72
+ ws.reload()
73
+
74
+ API document: http://gimite.net/doc/google-drive-ruby/
75
+
76
+
77
+ = Source code
78
+
79
+ http://github.com/gimite/google-drive-ruby
80
+
81
+ The license of this source is "New BSD Licence"
82
+
83
+
84
+ = Supported environments
85
+
86
+ Ruby 1.8.x and Ruby 1.9.x. Checked with Ruby 1.8.7 and Ruby 1.9.3.
87
+
88
+
89
+ = Author
90
+
91
+ 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,115 @@
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
+ module GoogleDrive
9
+
10
+ # ACL (access control list) of a spreadsheet.
11
+ #
12
+ # Use GoogleDrive::Spreadsheet#acl to get GoogleDrive::Acl object.
13
+ # See GoogleDrive::Spreadsheet#acl for usage example.
14
+ #
15
+ # This code is based on https://github.com/guyboertje/gdata-spreadsheet-ruby .
16
+ class Acl
17
+
18
+ include(Util)
19
+ extend(Forwardable)
20
+
21
+ def initialize(session, acls_feed_url) #:nodoc:
22
+ @session = session
23
+ @acls_feed_url = acls_feed_url
24
+ header = {"GData-Version" => "3.0"}
25
+ doc = @session.request(:get, @acls_feed_url, :header => header, :auth => :writely)
26
+ @acls = doc.css("entry").map(){ |e| AclEntry.new(entry_to_params(e)) }
27
+ end
28
+
29
+ def_delegators(:@acls, :size, :[], :each)
30
+
31
+ # Adds a new entry. +entry+ is either a GoogleDrive::AclEntry or a Hash with keys
32
+ # :scope_type, :scope and :role. See GoogleDrive::AclEntry#scope_type and
33
+ # GoogleDrive::AclEntry#role for the document of the fields.
34
+ #
35
+ # NOTE: This sends email to the new people.
36
+ #
37
+ # e.g.
38
+ # # A specific user can read or write.
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
+ # # Publish on the Web.
44
+ # spreadsheet.acl.push(
45
+ # {:scope_type => "default", :role => "reader"})
46
+ # # Anyone who knows the link can read.
47
+ # spreadsheet.acl.push(
48
+ # {:scope_type => "default", :with_key => true, :role => "reader"})
49
+ def push(entry)
50
+
51
+ entry = AclEntry.new(entry) if entry.is_a?(Hash)
52
+
53
+ header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
54
+ doc = @session.request(
55
+ :post, @acls_feed_url, :data => entry.to_xml(), :header => header, :auth => :writely)
56
+
57
+ entry.params = entry_to_params(doc.root)
58
+ @acls.push(entry)
59
+ return entry
60
+
61
+ end
62
+
63
+ # Deletes an ACL entry.
64
+ #
65
+ # e.g.
66
+ # spreadsheet.acl.delete(spreadsheet.acl[1])
67
+ def delete(entry)
68
+ header = {"GData-Version" => "3.0"}
69
+ @session.request(:delete, entry.edit_url, :header => header, :auth => :writely)
70
+ @acls.delete(entry)
71
+ end
72
+
73
+ def update_role(entry, role) #:nodoc:
74
+
75
+ header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
76
+ doc = @session.request(
77
+ :put, entry.edit_url, :data => entry.to_xml(), :header => header, :auth => :writely)
78
+
79
+ entry.params = entry_to_params(doc.root)
80
+ return entry
81
+
82
+ end
83
+
84
+ def inspect
85
+ return "\#<%p %p>" % [self.class, @acls]
86
+ end
87
+
88
+ private
89
+
90
+ def entry_to_params(entry)
91
+
92
+ if !entry.css("gAcl|withKey").empty?
93
+ with_key = true
94
+ role = entry.css("gAcl|withKey gAcl|role")[0]["value"]
95
+ else
96
+ with_key = false
97
+ role = entry.css("gAcl|role")[0]["value"]
98
+ end
99
+
100
+ return {
101
+ :acl => self,
102
+ :scope_type => entry.css("gAcl|scope")[0]["type"],
103
+ :scope => entry.css("gAcl|scope")[0]["value"],
104
+ :with_key => with_key,
105
+ :role => role,
106
+ :title => entry.css("title").text,
107
+ :edit_url => entry.css("link[rel='edit']")[0]["href"],
108
+ :etag => entry["etag"],
109
+ }
110
+
111
+ end
112
+
113
+ end
114
+
115
+ end
@@ -0,0 +1,89 @@
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
+ # Author: Phuogn Nguyen <https://github.com/phuongnd08>
5
+ # The license of this source is "New BSD Licence"
6
+
7
+ module GoogleDrive
8
+
9
+ # An entry of an ACL (access control list) of a spreadsheet.
10
+ #
11
+ # Use GoogleDrive::Acl#[] to get GoogleDrive::AclEntry object.
12
+ #
13
+ # This code is based on https://github.com/guyboertje/gdata-spreadsheet-ruby .
14
+ class AclEntry
15
+
16
+ include(Util)
17
+
18
+ PARAM_NAMES = [:acl, :scope_type, :scope, :with_key, :role, :title, :edit_url, :etag] #:nodoc:
19
+
20
+ # +params+ is a Hash object with keys +:scope_type+, +:scope+ and +:role+.
21
+ # See scope_type and role for the document of the fields.
22
+ def initialize(params)
23
+ @params = {:role => "reader"}
24
+ for name, value in params
25
+ if !name.is_a?(Symbol)
26
+ raise(ArgumentError, "Key must be Symbol, but is %p" % name)
27
+ elsif !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, with_key=%p, role=%p>" %
52
+ [self.class, @params[:scope_type], @params[:scope], @params[:with_key], @params[:role]]
53
+ end
54
+
55
+ def to_xml() #:nodoc:
56
+
57
+ etag_attr = self.etag ? "gd:etag='#{h(self.etag)}'" : ""
58
+ value_attr = self.scope ? "value='#{h(self.scope)}'" : ""
59
+ if self.with_key
60
+ role_tag = <<-EOS
61
+ <gAcl:withKey key='[ACL KEY]'>
62
+ <gAcl:role value='#{h(self.role)}'/>
63
+ </gAcl:withKey>
64
+ EOS
65
+ else
66
+ role_tag = <<-EOS
67
+ <gAcl:role value='#{h(self.role)}'/>
68
+ EOS
69
+ end
70
+
71
+ return <<-EOS
72
+ <entry
73
+ xmlns='http://www.w3.org/2005/Atom'
74
+ xmlns:gAcl='http://schemas.google.com/acl/2007'
75
+ xmlns:gd='http://schemas.google.com/g/2005'
76
+ #{etag_attr}>
77
+ <category scheme='http://schemas.google.com/g/2005#kind'
78
+ term='http://schemas.google.com/acl/2007#accessRule'/>
79
+ #{role_tag}
80
+ <gAcl:scope type='#{h(self.scope_type)}' #{value_attr}/>
81
+ </entry>
82
+ EOS
83
+
84
+ end
85
+
86
+ end
87
+
88
+ end
89
+
@@ -0,0 +1,14 @@
1
+ # Author: Hiroshi Ichikawa <http://gimite.net/>
2
+ # The license of this source is "New BSD Licence"
3
+
4
+ require "google_drive/error"
5
+
6
+
7
+ module GoogleDrive
8
+
9
+ # Raised when GoogleDrive.login has failed.
10
+ class AuthenticationError < GoogleDrive::Error
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1,56 @@
1
+ # Author: Hiroshi Ichikawa <http://gimite.net/>
2
+ # The license of this source is "New BSD Licence"
3
+
4
+ require "net/https"
5
+ require "uri"
6
+ Net::HTTP.version_1_2
7
+
8
+
9
+ module GoogleDrive
10
+
11
+ class ClientLoginFetcher #:nodoc:
12
+
13
+ def initialize(auth_tokens, proxy)
14
+ @auth_tokens = auth_tokens
15
+ if proxy
16
+ @proxy = proxy
17
+ elsif ENV["http_proxy"] && !ENV["http_proxy"].empty?
18
+ proxy_url = URI.parse(ENV["http_proxy"])
19
+ @proxy = Net::HTTP.Proxy(proxy_url.host, proxy_url.port)
20
+ else
21
+ @proxy = Net::HTTP
22
+ end
23
+ end
24
+
25
+ attr_accessor(:auth_tokens)
26
+
27
+ def request_raw(method, url, data, extra_header, auth)
28
+ uri = URI.parse(url)
29
+ http = @proxy.new(uri.host, uri.port)
30
+ http.use_ssl = true
31
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
32
+ http.start() do
33
+ path = uri.path + (uri.query ? "?#{uri.query}" : "")
34
+ header = auth_header(auth).merge(extra_header)
35
+ if method == :delete || method == :get
36
+ return http.__send__(method, path, header)
37
+ else
38
+ return http.__send__(method, path, data, header)
39
+ end
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def auth_header(auth)
46
+ token = auth == :none ? nil : @auth_tokens[auth]
47
+ if token
48
+ return {"Authorization" => "GoogleLogin auth=#{token}"}
49
+ else
50
+ return {}
51
+ end
52
+ end
53
+
54
+ end
55
+
56
+ end
@@ -0,0 +1,139 @@
1
+ # Author: Hiroshi Ichikawa <http://gimite.net/>
2
+ # The license of this source is "New BSD Licence"
3
+
4
+ require "google_drive/util"
5
+ require "google_drive/error"
6
+ require "google_drive/spreadsheet"
7
+
8
+
9
+ module GoogleDrive
10
+
11
+ # Use GoogleDrive::Session#root_collection, GoogleDrive::Collection#subcollections,
12
+ # or GoogleDrive::Session#collection_by_url to get GoogleDrive::Collection object.
13
+ class Collection < GoogleDrive::File
14
+
15
+ include(Util)
16
+
17
+ ROOT_URL = "#{DOCS_BASE_URL}/folder%3Aroot" #:nodoc:
18
+
19
+ alias collection_feed_url document_feed_url
20
+
21
+ def contents_url
22
+ if self.root?
23
+ # The root collection doesn't have document feed.
24
+ return concat_url(ROOT_URL, "/contents")
25
+ else
26
+ return self.document_feed_entry.css(
27
+ "content[type='application/atom+xml;type=feed']")[0]["src"]
28
+ end
29
+ end
30
+
31
+ # Title of the collection.
32
+ #
33
+ # Set <tt>params[:reload]</tt> to true to force reloading the title.
34
+ def title(params = {})
35
+ if self.root?
36
+ # The root collection doesn't have document feed.
37
+ return nil
38
+ else
39
+ return super
40
+ end
41
+ end
42
+
43
+ def resource_id
44
+ return self.root? ? nil : super
45
+ end
46
+
47
+ # Adds the given GoogleDrive::File to the collection.
48
+ def add(file)
49
+ header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
50
+ xml = <<-"EOS"
51
+ <entry xmlns="http://www.w3.org/2005/Atom">
52
+ <id>#{h(file.document_feed_url)}</id>
53
+ </entry>
54
+ EOS
55
+ @session.request(
56
+ :post, self.contents_url, :data => xml, :header => header, :auth => :writely)
57
+ return nil
58
+ end
59
+
60
+ # Creates a sub-collection with given title. Returns GoogleDrive::Collection object.
61
+ def create_subcollection(title)
62
+ header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
63
+ xml = <<-EOS
64
+ <entry xmlns="http://www.w3.org/2005/Atom">
65
+ <category scheme="http://schemas.google.com/g/2005#kind"
66
+ term="http://schemas.google.com/docs/2007#folder"/>
67
+ <title>#{h(title)}</title>
68
+ </entry>
69
+ EOS
70
+ doc = @session.request(
71
+ :post, contents_url, :data => xml, :header => header, :auth => :writely)
72
+ return @session.entry_element_to_file(doc)
73
+ end
74
+
75
+ # Removes the given GoogleDrive::File from the collection.
76
+ def remove(file)
77
+ url = to_v3_url("#{contents_url}/#{file.resource_id}")
78
+ @session.request(:delete, url, :auth => :writely, :header => {"If-Match" => "*"})
79
+ end
80
+
81
+ # Returns true if this is a root collection
82
+ def root?
83
+ self.document_feed_url == ROOT_URL
84
+ end
85
+
86
+ # Returns all the files (including spreadsheets, documents, subcollections) in the collection.
87
+ #
88
+ # You can specify query parameters described at
89
+ # https://developers.google.com/google-apps/documents-list/#getting_a_list_of_documents_and_files
90
+ #
91
+ # e.g.
92
+ #
93
+ # # Gets all the files in collection, including subcollections.
94
+ # collection.files
95
+ #
96
+ # # Gets only files with title "hoge".
97
+ # collection.files("title" => "hoge", "title-exact" => "true")
98
+ def files(params = {})
99
+ return files_with_type(nil, params)
100
+ end
101
+
102
+ alias contents files
103
+
104
+ # Returns all the spreadsheets in the collection.
105
+ def spreadsheets(params = {})
106
+ return files_with_type("spreadsheet", params)
107
+ end
108
+
109
+ # Returns all the Google Docs documents in the collection.
110
+ def documents(params = {})
111
+ return files_with_type("document", params)
112
+ end
113
+
114
+ # Returns all its subcollections.
115
+ def subcollections(params = {})
116
+ return files_with_type("folder", params)
117
+ end
118
+
119
+ # Returns its subcollection whose title exactly matches +title+ as GoogleDrive::Collection.
120
+ # Returns nil if not found. If multiple collections with the +title+ are found, returns
121
+ # one of them.
122
+ def subcollection_by_title(title)
123
+ return subcollections("title" => title, "title-exact" => "true")[0]
124
+ end
125
+
126
+ private
127
+
128
+ def files_with_type(type, params = {})
129
+ contents_url = self.contents_url
130
+ contents_url = concat_url(contents_url, "/-/#{type}") if type
131
+ contents_url = concat_url(contents_url, "?" + encode_query(params))
132
+ header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml"}
133
+ doc = @session.request(:get, contents_url, :header => header, :auth => :writely)
134
+ return doc.css("feed > entry").map(){ |e| @session.entry_element_to_file(e) }
135
+ end
136
+
137
+ end
138
+
139
+ end
@@ -0,0 +1,12 @@
1
+ # Author: Hiroshi Ichikawa <http://gimite.net/>
2
+ # The license of this source is "New BSD Licence"
3
+
4
+
5
+ module GoogleDrive
6
+
7
+ # Raised when spreadsheets.google.com has returned error.
8
+ class Error < RuntimeError
9
+
10
+ end
11
+
12
+ end