gdata-georgedrummond 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/LICENSE +202 -0
  2. data/README +102 -0
  3. data/Rakefile +64 -0
  4. data/lib/gdata.rb +21 -0
  5. data/lib/gdata/auth.rb +22 -0
  6. data/lib/gdata/auth/authsub.rb +161 -0
  7. data/lib/gdata/auth/clientlogin.rb +102 -0
  8. data/lib/gdata/client.rb +84 -0
  9. data/lib/gdata/client/apps.rb +27 -0
  10. data/lib/gdata/client/base.rb +182 -0
  11. data/lib/gdata/client/blogger.rb +28 -0
  12. data/lib/gdata/client/booksearch.rb +28 -0
  13. data/lib/gdata/client/calendar.rb +58 -0
  14. data/lib/gdata/client/contacts.rb +28 -0
  15. data/lib/gdata/client/doclist.rb +28 -0
  16. data/lib/gdata/client/finance.rb +28 -0
  17. data/lib/gdata/client/gbase.rb +28 -0
  18. data/lib/gdata/client/gmail.rb +28 -0
  19. data/lib/gdata/client/health.rb +28 -0
  20. data/lib/gdata/client/notebook.rb +28 -0
  21. data/lib/gdata/client/photos.rb +29 -0
  22. data/lib/gdata/client/spreadsheets.rb +28 -0
  23. data/lib/gdata/client/webmaster_tools.rb +28 -0
  24. data/lib/gdata/client/youtube.rb +47 -0
  25. data/lib/gdata/http.rb +18 -0
  26. data/lib/gdata/http/default_service.rb +82 -0
  27. data/lib/gdata/http/mime_body.rb +95 -0
  28. data/lib/gdata/http/request.rb +74 -0
  29. data/lib/gdata/http/response.rb +44 -0
  30. data/test/tc_gdata_auth_authsub.rb +53 -0
  31. data/test/tc_gdata_auth_clientlogin.rb +59 -0
  32. data/test/tc_gdata_client_base.rb +37 -0
  33. data/test/tc_gdata_client_calendar.rb +40 -0
  34. data/test/tc_gdata_client_photos.rb +65 -0
  35. data/test/tc_gdata_client_youtube.rb +77 -0
  36. data/test/tc_gdata_http_mime_body.rb +46 -0
  37. data/test/tc_gdata_http_request.rb +36 -0
  38. data/test/test_helper.rb +47 -0
  39. data/test/testimage.jpg +0 -0
  40. data/test/ts_gdata.rb +42 -0
  41. data/test/ts_gdata_auth.rb +25 -0
  42. data/test/ts_gdata_client.rb +29 -0
  43. data/test/ts_gdata_http.rb +25 -0
  44. metadata +94 -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,53 @@
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
+ $:.unshift(File.dirname(__FILE__))
16
+ require 'test_helper'
17
+
18
+ class TC_GData_Auth_AuthSub < Test::Unit::TestCase
19
+
20
+ include TestHelper
21
+
22
+ def test_make_authenticated_request
23
+ token = self.get_authsub_token()
24
+ key = self.get_authsub_private_key()
25
+ service = GData::Client::YouTube.new
26
+ if token
27
+
28
+ service.authsub_token = token
29
+ if key
30
+ service.authsub_private_key = key
31
+ end
32
+
33
+ feed = service.get('http://gdata.youtube.com/feeds/api/users/default/uploads?max-results=1')
34
+ self.assert_not_nil(feed, 'Feed should not be nil')
35
+ end
36
+ end
37
+
38
+ def test_generate_url
39
+ scope = 'http://gdata.youtube.com'
40
+ next_url = 'http://example.com'
41
+ secure = true
42
+ session = false
43
+ url = GData::Auth::AuthSub.get_url(next_url, scope, secure, session)
44
+ 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)
45
+
46
+ # test generating with a pre-populated scope
47
+ yt = GData::Client::YouTube.new
48
+ client_url = yt.authsub_url(next_url, secure, session)
49
+ self.assert_equal(url, client_url)
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,59 @@
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
+ $:.unshift(File.dirname(__FILE__))
16
+ require 'test_helper'
17
+
18
+ class TC_GData_Auth_ClientLogin < Test::Unit::TestCase
19
+
20
+ include TestHelper
21
+
22
+ def test_has_config
23
+ self.assert_not_nil(self.get_username(),
24
+ 'Must have a username in test_config.yml')
25
+ self.assert_not_nil(self.get_password(),
26
+ 'Must have a password in test_config.yml')
27
+ end
28
+
29
+ def test_get_token
30
+ client_login = GData::Auth::ClientLogin.new('cl')
31
+ source = 'GDataUnitTest'
32
+ assert_nothing_raised do
33
+ token = client_login.get_token(self.get_username(), self.get_password(), source)
34
+ end
35
+ end
36
+
37
+ def test_all_clients
38
+ source = 'GDataUnitTest'
39
+ GData::Client.constants.each do |const_name|
40
+ const = GData::Client.const_get(const_name)
41
+ if const.superclass == GData::Client::Base
42
+ instance = const.new
43
+ assert_nothing_raised do
44
+ instance.clientlogin(self.get_username(), self.get_password(), source)
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ def test_specify_account_type
51
+ gp = GData::Client::Photos.new
52
+ gp.source = 'GDataUnitTest'
53
+ assert_nothing_raised do
54
+ token = gp.clientlogin(self.get_username(), self.get_password(), nil, nil, nil, 'GOOGLE')
55
+ end
56
+ end
57
+
58
+
59
+ end
@@ -0,0 +1,37 @@
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
+ $:.unshift(File.dirname(__FILE__))
16
+ require 'test_helper'
17
+
18
+ class TC_GData_Client_Base < Test::Unit::TestCase
19
+
20
+ include TestHelper
21
+
22
+ def test_simple_gdata_get
23
+ service = GData::Client::Base.new
24
+ feed = service.get('http://gdata.youtube.com/feeds/base/videos?max-results=1').to_xml
25
+ assert_not_nil(feed, 'feed can not be nil')
26
+ end
27
+
28
+ def test_clientlogin_with_service
29
+ service = GData::Client::Base.new
30
+ service.clientlogin(self.get_username(), self.get_password(), nil, nil,
31
+ 'youtube')
32
+ feed = service.get('http://gdata.youtube.com/feeds/api/users/default/uploads?max-results=1').to_xml
33
+ assert_not_nil(feed, 'feed can not be nil')
34
+ end
35
+
36
+ end
37
+
@@ -0,0 +1,40 @@
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
+ $:.unshift(File.dirname(__FILE__))
16
+ require 'test_helper'
17
+
18
+ class TC_GData_Client_Calendar < Test::Unit::TestCase
19
+
20
+ include TestHelper
21
+
22
+ def setup
23
+ @cl = GData::Client::Calendar.new
24
+ @cl.clientlogin(self.get_username, self.get_password)
25
+ end
26
+
27
+ def test_get_all_calendars
28
+ response = @cl.get('http://www.google.com/calendar/feeds/default/allcalendars/full')
29
+ self.assert_equal(200, response.status_code, 'Must not be a redirect.')
30
+ self.assert_not_nil(@cl.session_cookie, 'Must have a session cookie.')
31
+ feed = response.to_xml
32
+ self.assert_not_nil(feed, 'feed can not be nil')
33
+
34
+ #login again to make sure the session cookie gets cleared
35
+ @cl.clientlogin(self.get_username, self.get_password)
36
+ self.assert_nil(@cl.session_cookie, 'Should clear session cookie.')
37
+ end
38
+
39
+
40
+ end
@@ -0,0 +1,65 @@
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
+ $:.unshift(File.dirname(__FILE__))
16
+ require 'test_helper'
17
+
18
+ class TC_GData_Client_Photos < Test::Unit::TestCase
19
+
20
+ include TestHelper
21
+
22
+ def setup
23
+ @gp = GData::Client::Photos.new
24
+ @gp.source = 'Ruby Client Unit Tests'
25
+ @gp.clientlogin(self.get_username(), self.get_password())
26
+ end
27
+
28
+ def test_authenticated_dropbox_feed
29
+ feed = @gp.get('http://picasaweb.google.com/data/feed/api/user/default/albumid/default?max-results=1').to_xml
30
+ self.assert_not_nil(feed, 'feed can not be nil')
31
+ end
32
+
33
+ def test_photo_upload
34
+ test_image = File.join(File.dirname(__FILE__), 'testimage.jpg')
35
+ mime_type = 'image/jpeg'
36
+
37
+ response = @gp.post_file('http://picasaweb.google.com/data/feed/api/user/default/albumid/default',
38
+ test_image, mime_type).to_xml
39
+
40
+ edit_uri = response.elements["link[@rel='edit']"].attributes['href']
41
+
42
+ @gp.delete(edit_uri)
43
+ end
44
+
45
+ def test_photo_upload_with_metadata
46
+ test_image = File.join(File.dirname(__FILE__), 'testimage.jpg')
47
+ mime_type = 'image/jpeg'
48
+
49
+ entry = <<-EOF
50
+ <entry xmlns='http://www.w3.org/2005/Atom'>
51
+ <title>ruby-client-testing.jpg</title>
52
+ <summary>Test case for Ruby Client Library.</summary>
53
+ <category scheme="http://schemas.google.com/g/2005#kind"
54
+ term="http://schemas.google.com/photos/2007#photo"/>
55
+ </entry>
56
+ EOF
57
+
58
+ response = @gp.post_file('http://picasaweb.google.com/data/feed/api/user/default/albumid/default',
59
+ test_image, mime_type, entry).to_xml
60
+
61
+ edit_uri = response.elements["link[@rel='edit']"].attributes['href']
62
+
63
+ @gp.delete(edit_uri)
64
+ end
65
+ end