gdata-19 1.1.2

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 (49) hide show
  1. data/.gitignore +8 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE +202 -0
  4. data/README +97 -0
  5. data/Rakefile +2 -0
  6. data/gdata.gemspec +44 -0
  7. data/lib/gdata.rb +24 -0
  8. data/lib/gdata/auth.rb +22 -0
  9. data/lib/gdata/auth/authsub.rb +161 -0
  10. data/lib/gdata/auth/clientlogin.rb +102 -0
  11. data/lib/gdata/client.rb +84 -0
  12. data/lib/gdata/client/apps.rb +27 -0
  13. data/lib/gdata/client/base.rb +182 -0
  14. data/lib/gdata/client/blogger.rb +28 -0
  15. data/lib/gdata/client/booksearch.rb +28 -0
  16. data/lib/gdata/client/calendar.rb +58 -0
  17. data/lib/gdata/client/contacts.rb +28 -0
  18. data/lib/gdata/client/doclist.rb +28 -0
  19. data/lib/gdata/client/finance.rb +28 -0
  20. data/lib/gdata/client/gbase.rb +28 -0
  21. data/lib/gdata/client/gmail.rb +28 -0
  22. data/lib/gdata/client/health.rb +28 -0
  23. data/lib/gdata/client/notebook.rb +28 -0
  24. data/lib/gdata/client/photos.rb +29 -0
  25. data/lib/gdata/client/spreadsheets.rb +28 -0
  26. data/lib/gdata/client/webmaster_tools.rb +28 -0
  27. data/lib/gdata/client/youtube.rb +47 -0
  28. data/lib/gdata/http.rb +18 -0
  29. data/lib/gdata/http/default_service.rb +82 -0
  30. data/lib/gdata/http/mime_body.rb +95 -0
  31. data/lib/gdata/http/request.rb +74 -0
  32. data/lib/gdata/http/response.rb +44 -0
  33. data/lib/gdata/version.rb +3 -0
  34. data/test/tc_gdata_auth_authsub.rb +54 -0
  35. data/test/tc_gdata_auth_clientlogin.rb +60 -0
  36. data/test/tc_gdata_client_base.rb +38 -0
  37. data/test/tc_gdata_client_calendar.rb +41 -0
  38. data/test/tc_gdata_client_photos.rb +66 -0
  39. data/test/tc_gdata_client_youtube.rb +78 -0
  40. data/test/tc_gdata_http_mime_body.rb +47 -0
  41. data/test/tc_gdata_http_request.rb +37 -0
  42. data/test/test_config.yml.example +7 -0
  43. data/test/test_helper.rb +47 -0
  44. data/test/testimage.jpg +0 -0
  45. data/test/ts_gdata.rb +44 -0
  46. data/test/ts_gdata_auth.rb +26 -0
  47. data/test/ts_gdata_client.rb +30 -0
  48. data/test/ts_gdata_http.rb +25 -0
  49. metadata +129 -0
@@ -0,0 +1,95 @@
1
+ # Copyright (C) 2008 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ module GData
17
+ module HTTP
18
+
19
+ # Class acts as a virtual file handle to a MIME multipart message body
20
+ class MimeBody
21
+
22
+ # The MIME boundary being used.
23
+ attr_reader :boundary
24
+
25
+ # All fields are required, the entry should be a string and is assumed
26
+ # to be XML.
27
+ def initialize(entry, file, file_mime_type)
28
+ @boundary = "END_OF_PART_#{rand(64000)}"
29
+ entry = wrap_entry(entry, file_mime_type)
30
+ closing_boundary = MimeBodyString.new("\r\n--#{@boundary}--")
31
+ @parts = [entry, file, closing_boundary]
32
+ @current_part = 0
33
+ end
34
+
35
+ # Implement read so that this class can be treated as a stream.
36
+ def read(bytes_requested)
37
+ if @current_part >= @parts.length
38
+ return false
39
+ end
40
+
41
+ buffer = @parts[@current_part].read(bytes_requested)
42
+
43
+ until buffer.length == bytes_requested
44
+ @current_part += 1
45
+ next_buffer = self.read(bytes_requested - buffer.length)
46
+ break if not next_buffer
47
+ buffer += next_buffer
48
+ end
49
+
50
+ return buffer
51
+ end
52
+
53
+ # Returns the content type of the message including boundary.
54
+ def content_type
55
+ return "multipart/related; boundary=\"#{@boundary}\""
56
+ end
57
+
58
+ private
59
+
60
+ # Sandwiches the entry body into a MIME message
61
+ def wrap_entry(entry, file_mime_type)
62
+ wrapped_entry = "--#{@boundary}\r\n"
63
+ wrapped_entry += "Content-Type: application/atom+xml\r\n\r\n"
64
+ wrapped_entry += entry
65
+ wrapped_entry += "\r\n--#{@boundary}\r\n"
66
+ wrapped_entry += "Content-Type: #{file_mime_type}\r\n\r\n"
67
+ return MimeBodyString.new(wrapped_entry)
68
+ end
69
+
70
+ end
71
+
72
+ # Class makes a string into a stream-like object
73
+ class MimeBodyString
74
+
75
+ def initialize(source_string)
76
+ @string = source_string
77
+ @bytes_read = 0
78
+ end
79
+
80
+ # Implement read so that this class can be treated as a stream.
81
+ def read(bytes_requested)
82
+ if @bytes_read == @string.length
83
+ return false
84
+ elsif bytes_requested > @string.length - @bytes_read
85
+ bytes_requested = @string.length - @bytes_read
86
+ end
87
+
88
+ buffer = @string[@bytes_read, bytes_requested]
89
+ @bytes_read += bytes_requested
90
+
91
+ return buffer
92
+ end
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,74 @@
1
+ # Copyright (C) 2008 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require "rexml/document"
16
+
17
+ module GData
18
+ module HTTP
19
+
20
+ # Very simple class to hold everything about an HTTP request.
21
+ class Request
22
+
23
+ # The URL of the request.
24
+ attr_accessor :url
25
+ # The body of the request.
26
+ attr_accessor :body
27
+ # The HTTP method being used in the request.
28
+ attr_accessor :method
29
+ # The HTTP headers of the request.
30
+ attr_accessor :headers
31
+
32
+ # Only the URL itself is required, everything else is optional.
33
+ def initialize(url, options = {})
34
+ @url = url
35
+ options.each do |key, value|
36
+ self.send("#{key}=", value)
37
+ end
38
+
39
+ @method ||= :get
40
+ @headers ||= {}
41
+ end
42
+
43
+ # Returns whether or not a request is chunked.
44
+ def chunked?
45
+ if @headers['Transfer-Encoding'] == 'chunked'
46
+ return true
47
+ else
48
+ return false
49
+ end
50
+ end
51
+
52
+ # Sets if the request is using chunked transfer-encoding.
53
+ def chunked=(enabled)
54
+ if enabled
55
+ @headers['Transfer-Encoding'] = 'chunked'
56
+ else
57
+ @headers.delete('Transfer-Encoding')
58
+ end
59
+ end
60
+
61
+ # Calculates and sets the length of the body.
62
+ def calculate_length!
63
+ if not @headers['Content-Length'] and not chunked? \
64
+ and method != :get and method != :delete
65
+ if @body
66
+ @headers['Content-Length'] = @body.length
67
+ else
68
+ @headers['Content-Length'] = 0
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,44 @@
1
+ # Copyright (C) 2008 Google Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'gdata/client'
16
+
17
+ module GData
18
+ module HTTP
19
+
20
+ # An extremely simple class to hold the values of an HTTP response.
21
+ class Response
22
+
23
+ # The HTTP response code.
24
+ attr_accessor :status_code
25
+ # The body of the HTTP response.
26
+ attr_accessor :body
27
+ # The headers of the HTTP response.
28
+ attr_accessor :headers
29
+
30
+ # Converts the response body into a REXML::Document
31
+ def to_xml
32
+ if @body
33
+ begin
34
+ return REXML::Document.new(@body).root
35
+ rescue
36
+ raise GData::Client::Error, "Response body not XML."
37
+ end
38
+ else
39
+ return nil
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module Gdata
2
+ VERSION = "1.1.2"
3
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+ # Copyright (C) 2008 Google Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ $:.unshift(File.dirname(__FILE__))
17
+ require 'test_helper'
18
+
19
+ class TC_GData_Auth_AuthSub < Test::Unit::TestCase
20
+
21
+ include TestHelper
22
+
23
+ def test_make_authenticated_request
24
+ token = self.get_authsub_token()
25
+ key = self.get_authsub_private_key()
26
+ service = GData::Client::YouTube.new
27
+ if token
28
+
29
+ service.authsub_token = token
30
+ if key
31
+ service.authsub_private_key = key
32
+ end
33
+
34
+ feed = service.get('http://gdata.youtube.com/feeds/api/users/default/uploads?max-results=1')
35
+ self.assert_not_nil(feed, 'Feed should not be nil')
36
+ end
37
+ end
38
+
39
+ def test_generate_url
40
+ scope = 'http://gdata.youtube.com'
41
+ next_url = 'http://example.com'
42
+ secure = true
43
+ session = false
44
+ url = GData::Auth::AuthSub.get_url(next_url, scope, secure, session)
45
+ self.assert_equal('https://www.google.com/accounts/AuthSubRequest?next=http%3A%2F%2Fexample.com&scope=http%3A%2F%2Fgdata.youtube.com&session=0&secure=1', url)
46
+
47
+ # test generating with a pre-populated scope
48
+ yt = GData::Client::YouTube.new
49
+ client_url = yt.authsub_url(next_url, secure, session)
50
+ self.assert_equal(url, client_url)
51
+
52
+ end
53
+
54
+ end
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+ # Copyright (C) 2008 Google Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ $:.unshift(File.dirname(__FILE__))
17
+ require 'test_helper'
18
+
19
+ class TC_GData_Auth_ClientLogin < Test::Unit::TestCase
20
+
21
+ include TestHelper
22
+
23
+ def test_has_config
24
+ self.assert_not_nil(self.get_username(),
25
+ 'Must have a username in test_config.yml')
26
+ self.assert_not_nil(self.get_password(),
27
+ 'Must have a password in test_config.yml')
28
+ end
29
+
30
+ def test_get_token
31
+ client_login = GData::Auth::ClientLogin.new('cl')
32
+ source = 'GDataUnitTest'
33
+ assert_nothing_raised do
34
+ token = client_login.get_token(self.get_username(), self.get_password(), source)
35
+ end
36
+ end
37
+
38
+ def test_all_clients
39
+ source = 'GDataUnitTest'
40
+ GData::Client.constants.each do |const_name|
41
+ const = GData::Client.const_get(const_name)
42
+ if const.superclass == GData::Client::Base
43
+ instance = const.new
44
+ assert_nothing_raised do
45
+ instance.clientlogin(self.get_username(), self.get_password(), source)
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def test_specify_account_type
52
+ gp = GData::Client::Photos.new
53
+ gp.source = 'GDataUnitTest'
54
+ assert_nothing_raised do
55
+ token = gp.clientlogin(self.get_username(), self.get_password(), nil, nil, nil, 'GOOGLE')
56
+ end
57
+ end
58
+
59
+
60
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+ # Copyright (C) 2008 Google Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ $:.unshift(File.dirname(__FILE__))
17
+ require 'test_helper'
18
+
19
+ class TC_GData_Client_Base < Test::Unit::TestCase
20
+
21
+ include TestHelper
22
+
23
+ def test_simple_gdata_get
24
+ service = GData::Client::Base.new
25
+ feed = service.get('http://gdata.youtube.com/feeds/base/videos?max-results=1').to_xml
26
+ assert_not_nil(feed, 'feed can not be nil')
27
+ end
28
+
29
+ def test_clientlogin_with_service
30
+ service = GData::Client::Base.new
31
+ service.clientlogin(self.get_username(), self.get_password(), nil, nil,
32
+ 'youtube')
33
+ feed = service.get('http://gdata.youtube.com/feeds/api/users/default/uploads?max-results=1').to_xml
34
+ assert_not_nil(feed, 'feed can not be nil')
35
+ end
36
+
37
+ end
38
+
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+ # Copyright (C) 2008 Google Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ $:.unshift(File.dirname(__FILE__))
17
+ require 'test_helper'
18
+
19
+ class TC_GData_Client_Calendar < Test::Unit::TestCase
20
+
21
+ include TestHelper
22
+
23
+ def setup
24
+ @cl = GData::Client::Calendar.new
25
+ @cl.clientlogin(self.get_username, self.get_password)
26
+ end
27
+
28
+ def test_get_all_calendars
29
+ response = @cl.get('http://www.google.com/calendar/feeds/default/allcalendars/full')
30
+ self.assert_equal(200, response.status_code, 'Must not be a redirect.')
31
+ self.assert_not_nil(@cl.session_cookie, 'Must have a session cookie.')
32
+ feed = response.to_xml
33
+ self.assert_not_nil(feed, 'feed can not be nil')
34
+
35
+ #login again to make sure the session cookie gets cleared
36
+ @cl.clientlogin(self.get_username, self.get_password)
37
+ self.assert_nil(@cl.session_cookie, 'Should clear session cookie.')
38
+ end
39
+
40
+
41
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ # Copyright (C) 2008 Google Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+
16
+ $:.unshift(File.dirname(__FILE__))
17
+ require 'test_helper'
18
+
19
+ class TC_GData_Client_Photos < Test::Unit::TestCase
20
+
21
+ include TestHelper
22
+
23
+ def setup
24
+ @gp = GData::Client::Photos.new
25
+ @gp.source = 'Ruby Client Unit Tests'
26
+ @gp.clientlogin(self.get_username(), self.get_password())
27
+ end
28
+
29
+ def test_authenticated_dropbox_feed
30
+ feed = @gp.get('http://picasaweb.google.com/data/feed/api/user/default/albumid/default?max-results=1').to_xml
31
+ self.assert_not_nil(feed, 'feed can not be nil')
32
+ end
33
+
34
+ def test_photo_upload
35
+ test_image = File.join(File.dirname(__FILE__), 'testimage.jpg')
36
+ mime_type = 'image/jpeg'
37
+
38
+ response = @gp.post_file('http://picasaweb.google.com/data/feed/api/user/default/albumid/default',
39
+ test_image, mime_type).to_xml
40
+
41
+ edit_uri = response.elements["link[@rel='edit']"].attributes['href']
42
+
43
+ @gp.delete(edit_uri)
44
+ end
45
+
46
+ def test_photo_upload_with_metadata
47
+ test_image = File.join(File.dirname(__FILE__), 'testimage.jpg')
48
+ mime_type = 'image/jpeg'
49
+
50
+ entry = <<-EOF
51
+ <entry xmlns='http://www.w3.org/2005/Atom'>
52
+ <title>ruby-client-testing.jpg</title>
53
+ <summary>Test case for Ruby Client Library.</summary>
54
+ <category scheme="http://schemas.google.com/g/2005#kind"
55
+ term="http://schemas.google.com/photos/2007#photo"/>
56
+ </entry>
57
+ EOF
58
+
59
+ response = @gp.post_file('http://picasaweb.google.com/data/feed/api/user/default/albumid/default',
60
+ test_image, mime_type, entry).to_xml
61
+
62
+ edit_uri = response.elements["link[@rel='edit']"].attributes['href']
63
+
64
+ @gp.delete(edit_uri)
65
+ end
66
+ end