google_drive 0.3.11 → 1.0.0.pre1

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.
Files changed (34) hide show
  1. checksums.yaml +7 -7
  2. data/README.rdoc +27 -10
  3. data/lib/google_drive/acl.rb +40 -58
  4. data/lib/google_drive/acl_entry.rb +76 -56
  5. data/lib/google_drive/api_client_fetcher.rb +49 -0
  6. data/lib/google_drive/collection.rb +69 -71
  7. data/lib/google_drive/file.rb +171 -128
  8. data/lib/google_drive/session.rb +234 -268
  9. data/lib/google_drive/spreadsheet.rb +19 -163
  10. data/lib/google_drive/util.rb +126 -17
  11. data/lib/google_drive/worksheet.rb +108 -80
  12. data/lib/google_drive.rb +63 -57
  13. data/lib/google_drive_v1/acl.rb +115 -0
  14. data/lib/google_drive_v1/acl_entry.rb +100 -0
  15. data/lib/google_drive_v1/api_client_fetcher.rb +47 -0
  16. data/lib/google_drive_v1/authentication_error.rb +14 -0
  17. data/lib/{google_drive → google_drive_v1}/basic_fetcher.rb +1 -1
  18. data/lib/{google_drive → google_drive_v1}/client_login_fetcher.rb +2 -2
  19. data/lib/google_drive_v1/collection.rb +167 -0
  20. data/lib/google_drive_v1/error.rb +12 -0
  21. data/lib/google_drive_v1/file.rb +258 -0
  22. data/lib/google_drive_v1/list.rb +119 -0
  23. data/lib/google_drive_v1/list_row.rb +88 -0
  24. data/lib/{google_drive → google_drive_v1}/oauth1_fetcher.rb +1 -1
  25. data/lib/{google_drive → google_drive_v1}/oauth2_fetcher.rb +2 -2
  26. data/lib/google_drive_v1/record.rb +31 -0
  27. data/lib/google_drive_v1/session.rb +522 -0
  28. data/lib/google_drive_v1/spreadsheet.rb +248 -0
  29. data/lib/google_drive_v1/table.rb +60 -0
  30. data/lib/google_drive_v1/util.rb +73 -0
  31. data/lib/google_drive_v1/worksheet.rb +498 -0
  32. data/lib/google_drive_v1.rb +148 -0
  33. metadata +112 -77
  34. data/doc_src/google_drive/acl_entry.rb +0 -33
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
- ---
2
- SHA512:
3
- metadata.gz: aacfb80c76656613c5a1735977c6e39796a1df82a5a8a97944381c289362eaefdfee229b1c586f94378f46a8357caec0030f00b7a032404e27f2f93f69934137
4
- data.tar.gz: d8f9abf36d3406863e85520041adc04b5a1c9e64b344331982ed89ae6d2296d27d54fc13bb000bdf1ca0dce497f5f0a740ea40441ee18d2100c4cc6fdf4e724c
5
- SHA1:
6
- metadata.gz: cc0c279d89eeff98e5a5a85f82287db36343402d
7
- data.tar.gz: 9cb3dff31f112e16654f61bef9049b938487e33c
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 76b903fb2d84303774103ab6da528579367ce8a5
4
+ data.tar.gz: 04f591af34df950ba24d46a0ba0f6e099447f291
5
+ SHA512:
6
+ metadata.gz: e5253faaa7c32a502d296354cc1aa1728c79136d009f45fb05801c21b490b4f6ec81c6995d3486c5742b9ecf96f7408ced12d08b3b46d2c9a729ba1d3379a148
7
+ data.tar.gz: f52470706946884dd09e400b8fff2bd22af076947083910f58b92177566a80c96c8a9c833307c6f4ce9bc181ed7f6fa69723eff4a4e23faa31c0c91dd91a9c60
data/README.rdoc CHANGED
@@ -1,4 +1,4 @@
1
- This is a Ruby 1.9/2.0 library to read/write files/spreadsheets in Google Drive/Docs.
1
+ This is a Ruby 1.8/1.9/2.0 library to read/write files/spreadsheets in Google Drive/Docs.
2
2
 
3
3
  NOTE: This is NOT a library to create Google Drive App.
4
4
 
@@ -10,15 +10,31 @@ NOTE: This is NOT a library to create Google Drive App.
10
10
 
11
11
  = How to use
12
12
 
13
+ First, follow "Create a client ID and client secret" in {this page}[https://developers.google.com/drive/web/auth/web-server] to get a client ID and client secret for OAuth.
14
+
13
15
  Example to read/write files in Google Drive:
14
16
 
15
17
  require "rubygems"
18
+ require "google/api_client"
16
19
  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")
20
+
21
+ # Authorizes with OAuth and gets an access token.
22
+ client = Google::APIClient.new
23
+ auth = client.authorization
24
+ auth.client_id = "YOUR CLIENT ID"
25
+ auth.client_secret = "YOUR CLIENT SECRET"
26
+ auth.scope =
27
+ "https://www.googleapis.com/auth/drive " +
28
+ "https://spreadsheets.google.com/feeds/"
29
+ auth.redirect_uri = "urn:ietf:wg:oauth:2.0:oob"
30
+ print("1. Open this page:\n%s\n\n" % auth.authorization_uri)
31
+ print("2. Enter the authorization code shown in the page: ")
32
+ auth.code = $stdin.gets.chomp
33
+ auth.fetch_access_token!
34
+ access_token = auth.access_token
35
+
36
+ # Creates a session.
37
+ session = GoogleDrive.login_with_oauth(access_token)
22
38
 
23
39
  # Gets list of remote files.
24
40
  for file in session.files
@@ -38,12 +54,13 @@ Example to read/write files in Google Drive:
38
54
  Example to read/write spreadsheets:
39
55
 
40
56
  require "rubygems"
57
+ require "google/api_client"
41
58
  require "google_drive"
59
+
60
+ # Same as the code above to get access_token...
42
61
 
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")
62
+ # Creates a session.
63
+ session = GoogleDrive.login(access_token)
47
64
 
48
65
  # First worksheet of
49
66
  # https://docs.google.com/spreadsheet/ccc?key=pz7XtlQC-PYx-jrVMJErTcg
@@ -18,15 +18,16 @@ module GoogleDrive
18
18
  include(Util)
19
19
  extend(Forwardable)
20
20
 
21
- def initialize(session, acls_feed_url) #:nodoc:
21
+ def initialize(session, file) #:nodoc:
22
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)) }
23
+ @file = file
24
+ api_result = @session.execute!(
25
+ :api_method => @session.drive.permissions.list,
26
+ :parameters => { "fileId" => @file.id })
27
+ @entries = api_result.data.items.map(){ |i| AclEntry.new(i, self) }
27
28
  end
28
29
 
29
- def_delegators(:@acls, :size, :[], :each)
30
+ def_delegators(:@entries, :size, :[], :each)
30
31
 
31
32
  # Adds a new entry. +entry+ is either a GoogleDrive::AclEntry or a Hash with keys
32
33
  # :scope_type, :scope and :role. See GoogleDrive::AclEntry#scope_type and
@@ -37,27 +38,28 @@ module GoogleDrive
37
38
  # e.g.
38
39
  # # A specific user can read or write.
39
40
  # spreadsheet.acl.push(
40
- # {:scope_type => "user", :scope => "example2@gmail.com", :role => "reader"})
41
+ # {:type => "user", :value => "example2@gmail.com", :role => "reader"})
41
42
  # spreadsheet.acl.push(
42
- # {:scope_type => "user", :scope => "example3@gmail.com", :role => "writer"})
43
+ # {:type => "user", :value => "example3@gmail.com", :role => "writer"})
43
44
  # # Publish on the Web.
44
45
  # spreadsheet.acl.push(
45
- # {:scope_type => "default", :role => "reader"})
46
+ # {:type => "anyone", :role => "reader"})
46
47
  # # Anyone who knows the link can read.
47
48
  # 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;charset=utf-8"}
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
-
49
+ # {:type => "anyone", :withLink => true, :role => "reader"})
50
+ #
51
+ # See here for parameter detais:
52
+ # https://developers.google.com/drive/v2/reference/permissions/insert
53
+ def push(params_or_entry)
54
+ entry = params_or_entry.is_a?(AclEntry) ? params_or_entry : AclEntry.new(params_or_entry)
55
+ new_permission = @session.drive.permissions.insert.request_schema.new(entry.params)
56
+ api_result = @session.execute!(
57
+ :api_method => @session.drive.permissions.insert,
58
+ :body_object => new_permission,
59
+ :parameters => { "fileId" => @file.id })
60
+ new_entry = AclEntry.new(api_result.data, self)
61
+ @entries.push(new_entry)
62
+ return new_entry
61
63
  end
62
64
 
63
65
  # Deletes an ACL entry.
@@ -65,49 +67,29 @@ module GoogleDrive
65
67
  # e.g.
66
68
  # spreadsheet.acl.delete(spreadsheet.acl[1])
67
69
  def delete(entry)
68
- header = {"GData-Version" => "3.0"}
69
- @session.request(:delete, entry.edit_url_internal, :header => header, :auth => :writely)
70
- @acls.delete(entry)
70
+ @session.execute!(
71
+ :api_method => @session.drive.permissions.delete,
72
+ :parameters => {
73
+ "fileId" => @file.id,
74
+ "permissionId" => entry.id,
75
+ })
76
+ @entries.delete(entry)
71
77
  end
72
78
 
73
79
  def update_role(entry) #:nodoc:
74
-
75
- header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml;charset=utf-8"}
76
- doc = @session.request(
77
- :put, entry.edit_url_internal, :data => entry.to_xml(), :header => header, :auth => :writely)
78
-
79
- entry.params = entry_to_params(doc.root)
80
+ api_result = @session.execute!(
81
+ :api_method => @session.drive.permissions.update,
82
+ :body_object => entry.api_permission,
83
+ :parameters => {
84
+ "fileId" => @file.id,
85
+ "permissionId" => entry.id,
86
+ })
87
+ entry.api_permission = api_result.data
80
88
  return entry
81
-
82
89
  end
83
90
 
84
91
  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
-
92
+ return "\#<%p %p>" % [self.class, @entries]
111
93
  end
112
94
 
113
95
  end
@@ -15,83 +15,103 @@ module GoogleDrive
15
15
 
16
16
  include(Util)
17
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
18
+ # +params_or_api_permission+ is a Hash object with keys +:type+, +:value+, +:role+ and +:withLink+.
19
+ # See GoogleDrive::Acl#push for description of the parameters.
20
+ def initialize(params_or_api_permission, acl = nil)
21
+ @acl = acl
22
+ if acl
23
+ @api_permission = params_or_api_permission
24
+ @params = nil
25
+ delegate_api_methods(self, @api_permission)
26
+ else
27
+ @api_permission = nil
28
+ @params = convert_params(params_or_api_permission)
31
29
  end
32
30
  end
33
31
 
34
- attr_accessor(:params) #:nodoc:
32
+ attr_reader(:acl)
33
+ attr_reader(:params) #:nodoc:
34
+ attr_accessor(:api_permission) #:nodoc:
35
35
 
36
- PARAM_NAMES.each() do |name|
37
- define_method(name) do
38
- return @params[name]
39
- end
36
+ # The role given to the scope. One of:
37
+ # - "owner": The owner.
38
+ # - "writer": With read/write access.
39
+ # - "reader": With read-only access.
40
+ def role
41
+ return @params ? @params["role"] : @api_permission.role
42
+ end
43
+
44
+ # Type of the scope. One of:
45
+ #
46
+ # - "user": value is a user's email address.
47
+ # - "group": value is a Google Group email address.
48
+ # - "domain": value is a Google Apps domain.
49
+ # - "anyone": Publicly shared with all users. value is +nil+.
50
+ def type
51
+ return @params ? @params["type"] : @api_permission.type
52
+ end
53
+
54
+ alias scope_type type
55
+
56
+ def additional_roles
57
+ return @params ? @params["additionalRoles"] : @api_permission.additional_roles
40
58
  end
41
59
 
42
- def edit_url
43
- warn(
44
- "WARNING: GoogleDrive::AclEntry\#edit_url is deprecated and will be removed in the next version.")
45
- return self.edit_url_internal
60
+ def id
61
+ return @params ? @params["id"] : @api_permission.id
46
62
  end
47
63
 
48
- def edit_url_internal #:nodoc:
49
- return @params[:edit_url]
64
+ # The value of the scope. See type.
65
+ def value
66
+ return @params ? @params["value"] : @api_permission.value
50
67
  end
51
68
 
69
+ alias scope value
70
+
71
+ # If +true+, the file is shared only with people who know the link.
72
+ def with_link
73
+ return @params ? @params["withLink"] : @api_permission.with_link
74
+ end
75
+
76
+ alias with_key with_link
77
+
52
78
  # Changes the role of the scope.
53
79
  #
54
80
  # e.g.
55
81
  # spreadsheet.acl[1].role = "writer"
56
82
  def role=(role)
57
- @params[:role] = role
58
- @params[:acl].update_role(self)
83
+ if @params
84
+ @params["role"] = role
85
+ else
86
+ @api_permission.role = role
87
+ @acl.update_role(self)
88
+ end
59
89
  end
60
90
 
61
91
  def inspect
62
- return "\#<%p scope_type=%p, scope=%p, with_key=%p, role=%p>" %
63
- [self.class, @params[:scope_type], @params[:scope], @params[:with_key], @params[:role]]
92
+ return "\#<%p type=%p, name=%p, role=%p>" %
93
+ [self.class, self.type, self.name, self.role]
64
94
  end
65
95
 
66
- def to_xml() #:nodoc:
67
-
68
- etag_attr = self.etag ? "gd:etag='#{h(self.etag)}'" : ""
69
- value_attr = self.scope ? "value='#{h(self.scope)}'" : ""
70
- if self.with_key
71
- role_tag = <<-EOS
72
- <gAcl:withKey key='[ACL KEY]'>
73
- <gAcl:role value='#{h(self.role)}'/>
74
- </gAcl:withKey>
75
- EOS
76
- else
77
- role_tag = <<-EOS
78
- <gAcl:role value='#{h(self.role)}'/>
79
- EOS
96
+ private
97
+
98
+ # Normalizes the key to String, and converts parameters in the old version.
99
+ def convert_params(orig_params)
100
+ new_params = {}
101
+ for k, v in orig_params
102
+ k = k.to_s()
103
+ case k
104
+ when "scope_type"
105
+ new_params["type"] = (v == "default" ? "anyone" : v)
106
+ when "scope"
107
+ new_params["value"] = v
108
+ when "with_key"
109
+ new_params["withLink"] = v
110
+ else
111
+ new_params[k] = v
112
+ end
80
113
  end
81
-
82
- return <<-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
- #{etag_attr}>
88
- <category scheme='http://schemas.google.com/g/2005#kind'
89
- term='http://schemas.google.com/acl/2007#accessRule'/>
90
- #{role_tag}
91
- <gAcl:scope type='#{h(self.scope_type)}' #{value_attr}/>
92
- </entry>
93
- EOS
94
-
114
+ return new_params
95
115
  end
96
116
 
97
117
  end
@@ -0,0 +1,49 @@
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 ApiClientFetcher
12
+
13
+ class Response
14
+
15
+ def initialize(client_response)
16
+ @client_response = client_response
17
+ end
18
+
19
+ def code
20
+ return @client_response.status.to_s()
21
+ end
22
+
23
+ def body
24
+ return @client_response.body
25
+ end
26
+
27
+ attr_reader(:client_response)
28
+
29
+ end
30
+
31
+ def initialize(client)
32
+ @client = client
33
+ @drive = @client.discovered_api("drive", "v2")
34
+ end
35
+
36
+ attr_reader(:client, :drive)
37
+
38
+ def request_raw(method, url, data, extra_header, auth)
39
+ client_response = @client.execute(
40
+ :http_method => method,
41
+ :uri => url,
42
+ :body => data,
43
+ :headers => extra_header)
44
+ return Response.new(client_response)
45
+ end
46
+
47
+ end
48
+
49
+ end
@@ -13,107 +13,97 @@ module GoogleDrive
13
13
  class Collection < GoogleDrive::File
14
14
 
15
15
  include(Util)
16
-
17
- ROOT_URL = "#{DOCS_BASE_URL}/folder%3Aroot" #:nodoc:
18
16
 
19
17
  alias collection_feed_url document_feed_url
20
18
 
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_internal.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
19
  # Adds the given GoogleDrive::File to the collection.
48
20
  def add(file)
49
- header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml;charset=utf-8"}
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)
21
+ new_child = @session.drive.children.insert.request_schema.new({
22
+ "id" => file.id,
23
+ })
24
+ @session.execute!(
25
+ :api_method => @session.drive.children.insert,
26
+ :body_object => new_child,
27
+ :parameters => {
28
+ "folderId" => self.id,
29
+ "childId" => file.id,
30
+ })
57
31
  return nil
58
32
  end
59
33
 
60
34
  # Creates a sub-collection with given title. Returns GoogleDrive::Collection object.
61
35
  def create_subcollection(title)
62
- header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml;charset=utf-8"}
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)
36
+ file = @session.drive.files.insert.request_schema.new({
37
+ "title" => title,
38
+ "mimeType" => "application/vnd.google-apps.folder",
39
+ "parents" => [{"id" => self.id}],
40
+ })
41
+ api_result = @session.execute!(
42
+ :api_method => @session.drive.files.insert,
43
+ :body_object => file)
44
+ return @session.wrap_api_file(api_result.data)
73
45
  end
74
46
 
75
47
  # Removes the given GoogleDrive::File from the collection.
76
48
  def remove(file)
77
- url = to_v3_url("#{contents_url}/#{file.resource_id}")
78
- @session.request(:delete, url, :auth => :writely, :header => {"If-Match" => "*"})
49
+ @session.execute!(
50
+ :api_method => @session.drive.children.delete,
51
+ :parameters => {
52
+ "folderId" => self.id,
53
+ "childId" => file.id,
54
+ })
55
+ return nil
79
56
  end
80
57
 
81
58
  # Returns true if this is a root collection
82
59
  def root?
83
- self.document_feed_url == ROOT_URL
60
+ return self.api_file.parents.empty?
84
61
  end
85
62
 
86
63
  # Returns all the files (including spreadsheets, documents, subcollections) in the collection.
87
64
  #
88
- # You can specify query parameters described at
89
- # https://developers.google.com/google-apps/documents-list/#getting_a_list_of_documents_and_files
65
+ # You can specify parameters documented at
66
+ # https://developers.google.com/drive/v2/reference/files/list
90
67
  #
91
68
  # e.g.
92
69
  #
93
70
  # # Gets all the files in collection, including subcollections.
94
71
  # collection.files
95
- #
96
72
  # # 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)
73
+ # collection.files("q" => "title = 'hoge'")
74
+ # # Same as above with a placeholder.
75
+ # collection.files("q" => ["title = ?", "hoge"])
76
+ #
77
+ # By default, it returns the first 100 files. See document of GoogleDrive::Session#files method
78
+ # for how to get all files.
79
+ def files(params = {}, &block)
80
+ return files_with_type(nil, params, &block)
100
81
  end
101
82
 
102
83
  alias contents files
103
84
 
104
85
  # Returns all the spreadsheets in the collection.
105
- def spreadsheets(params = {})
106
- return files_with_type("spreadsheet", params)
86
+ #
87
+ # By default, it returns the first 100 spreadsheets. See document of GoogleDrive::Session#files method
88
+ # for how to get all spreadsheets.
89
+ def spreadsheets(params = {}, &block)
90
+ return files_with_type("application/vnd.google-apps.spreadsheet", params, &block)
107
91
  end
108
92
 
109
93
  # Returns all the Google Docs documents in the collection.
110
- def documents(params = {})
111
- return files_with_type("document", params)
94
+ #
95
+ # By default, it returns the first 100 documents. See document of GoogleDrive::Session#files method
96
+ # for how to get all documents.
97
+ def documents(params = {}, &block)
98
+ return files_with_type("application/vnd.google-apps.document", params, &block)
112
99
  end
113
100
 
114
101
  # Returns all its subcollections.
115
- def subcollections(params = {})
116
- return files_with_type("folder", params)
102
+ #
103
+ # By default, it returns the first 100 subcollections. See document of GoogleDrive::Session#files method
104
+ # for how to get all subcollections.
105
+ def subcollections(params = {}, &block)
106
+ return files_with_type("application/vnd.google-apps.folder", params, &block)
117
107
  end
118
108
 
119
109
  # Returns a file (can be a spreadsheet, document, subcollection or other files) in the
@@ -132,7 +122,12 @@ module GoogleDrive
132
122
  #
133
123
  # If given an Array, does a recursive subcollection traversal.
134
124
  def subcollection_by_title(title)
135
- return file_by_title_with_type(title, "folder")
125
+ return file_by_title_with_type(title, "application/vnd.google-apps.folder")
126
+ end
127
+
128
+ # Returns URL of the deprecated contents feed.
129
+ def contents_url
130
+ self.document_feed_url + "/contents"
136
131
  end
137
132
 
138
133
  protected
@@ -147,19 +142,22 @@ module GoogleDrive
147
142
  return parent && parent.file_by_title_with_type(rel_path[-1], type)
148
143
  end
149
144
  else
150
- return files_with_type(type, "title" => title, "title-exact" => "true")[0]
145
+ return files_with_type(type, "q" => ["title = ?", title], "maxResults" => 1)[0]
151
146
  end
152
147
  end
153
148
 
154
149
  private
155
150
 
156
- def files_with_type(type, params = {})
157
- contents_url = self.contents_url
158
- contents_url = concat_url(contents_url, "/-/#{type}") if type
159
- contents_url = concat_url(contents_url, "?" + encode_query(params))
160
- header = {"GData-Version" => "3.0", "Content-Type" => "application/atom+xml;charset=utf-8"}
161
- doc = @session.request(:get, contents_url, :header => header, :auth => :writely)
162
- return doc.css("feed > entry").map(){ |e| @session.entry_element_to_file(e) }
151
+ def files_with_type(type, params = {}, &block)
152
+ params = convert_params(params)
153
+ query = construct_and_query([
154
+ ["? in parents", self.id],
155
+ type ? ["mimeType = ?", type] : nil,
156
+ params["q"],
157
+ ])
158
+ params = params.merge({"q" => query})
159
+ # This is faster than calling children.list and then files.get for each file.
160
+ return @session.files(params, &block)
163
161
  end
164
162
 
165
163
  end