gdata-19 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
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