jkarlsson-gdata 1.1.1

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 (46) hide show
  1. data/LICENSE +202 -0
  2. data/README +97 -0
  3. data/Rakefile +64 -0
  4. data/lib/gdata.rb +22 -0
  5. data/lib/gdata/auth.rb +23 -0
  6. data/lib/gdata/auth/authsub.rb +161 -0
  7. data/lib/gdata/auth/clientlogin.rb +102 -0
  8. data/lib/gdata/auth/oauth.rb +129 -0
  9. data/lib/gdata/client.rb +84 -0
  10. data/lib/gdata/client/apps.rb +27 -0
  11. data/lib/gdata/client/base.rb +187 -0
  12. data/lib/gdata/client/blogger.rb +28 -0
  13. data/lib/gdata/client/booksearch.rb +28 -0
  14. data/lib/gdata/client/calendar.rb +58 -0
  15. data/lib/gdata/client/contacts.rb +28 -0
  16. data/lib/gdata/client/doclist.rb +28 -0
  17. data/lib/gdata/client/finance.rb +28 -0
  18. data/lib/gdata/client/gbase.rb +28 -0
  19. data/lib/gdata/client/gmail.rb +28 -0
  20. data/lib/gdata/client/health.rb +28 -0
  21. data/lib/gdata/client/notebook.rb +28 -0
  22. data/lib/gdata/client/photos.rb +29 -0
  23. data/lib/gdata/client/spreadsheets.rb +28 -0
  24. data/lib/gdata/client/webmaster_tools.rb +28 -0
  25. data/lib/gdata/client/youtube.rb +47 -0
  26. data/lib/gdata/http.rb +18 -0
  27. data/lib/gdata/http/default_service.rb +82 -0
  28. data/lib/gdata/http/mime_body.rb +106 -0
  29. data/lib/gdata/http/request.rb +74 -0
  30. data/lib/gdata/http/response.rb +44 -0
  31. data/test/tc_gdata_auth_authsub.rb +53 -0
  32. data/test/tc_gdata_auth_clientlogin.rb +59 -0
  33. data/test/tc_gdata_client_base.rb +37 -0
  34. data/test/tc_gdata_client_calendar.rb +40 -0
  35. data/test/tc_gdata_client_photos.rb +65 -0
  36. data/test/tc_gdata_client_youtube.rb +77 -0
  37. data/test/tc_gdata_http_mime_body.rb +46 -0
  38. data/test/tc_gdata_http_request.rb +36 -0
  39. data/test/test_config.yml.example +7 -0
  40. data/test/test_helper.rb +47 -0
  41. data/test/testimage.jpg +0 -0
  42. data/test/ts_gdata.rb +42 -0
  43. data/test/ts_gdata_auth.rb +25 -0
  44. data/test/ts_gdata_client.rb +29 -0
  45. data/test/ts_gdata_http.rb +25 -0
  46. metadata +111 -0
@@ -0,0 +1,18 @@
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/http/default_service'
16
+ require 'gdata/http/mime_body'
17
+ require 'gdata/http/request'
18
+ require 'gdata/http/response'
@@ -0,0 +1,82 @@
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 'net/http'
16
+ require 'net/https'
17
+ require 'uri'
18
+
19
+ module GData
20
+ module HTTP
21
+
22
+ # This is the default implementation of the HTTP layer that uses
23
+ # Net::HTTP. You could roll your own if you have different requirements
24
+ # or cannot use Net::HTTP for some reason.
25
+ class DefaultService
26
+
27
+ # Take a GData::HTTP::Request, execute the request, and return a
28
+ # GData::HTTP::Response object.
29
+ def make_request(request)
30
+ url = URI.parse(request.url)
31
+ http = Net::HTTP.new(url.host, url.port)
32
+ http.use_ssl = (url.scheme == 'https')
33
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
34
+
35
+ case request.method
36
+ when :get
37
+ req = Net::HTTP::Get.new(url.request_uri)
38
+ when :put
39
+ req = Net::HTTP::Put.new(url.request_uri)
40
+ when :post
41
+ req = Net::HTTP::Post.new(url.request_uri)
42
+ when :delete
43
+ req = Net::HTTP::Delete.new(url.request_uri)
44
+ else
45
+ raise ArgumentError, "Unsupported HTTP method specified."
46
+ end
47
+
48
+ case request.body
49
+ when String
50
+ req.body = request.body
51
+ when Hash
52
+ req.set_form_data(request.body)
53
+ when File
54
+ req.body_stream = request.body
55
+ request.chunked = true
56
+ when GData::HTTP::MimeBody
57
+ req.body_stream = request.body
58
+ request.chunked = true
59
+ else
60
+ req.body = request.body.to_s
61
+ end
62
+
63
+ request.headers.each do |key, value|
64
+ req[key] = value
65
+ end
66
+
67
+ request.calculate_length!
68
+
69
+ res = http.request(req)
70
+
71
+ response = Response.new
72
+ response.body = res.body
73
+ response.headers = Hash.new
74
+ res.each do |key, value|
75
+ response.headers[key] = value
76
+ end
77
+ response.status_code = res.code.to_i
78
+ return response
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,106 @@
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
+ # Reset the stream so that it can be read again
36
+ def rewind
37
+ @current_part = 0
38
+ @parts.map { |p| p.rewind }
39
+ end
40
+
41
+
42
+ # Implement read so that this class can be treated as a stream.
43
+ def read(bytes_requested)
44
+ if @current_part >= @parts.length
45
+ return false
46
+ end
47
+
48
+ buffer = @parts[@current_part].read(bytes_requested)
49
+
50
+ until buffer.length == bytes_requested
51
+ @current_part += 1
52
+ next_buffer = self.read(bytes_requested - buffer.length)
53
+ break if not next_buffer
54
+ buffer += next_buffer
55
+ end
56
+
57
+ return buffer
58
+ end
59
+
60
+ # Returns the content type of the message including boundary.
61
+ def content_type
62
+ return "multipart/related; boundary=\"#{@boundary}\""
63
+ end
64
+
65
+ private
66
+
67
+ # Sandwiches the entry body into a MIME message
68
+ def wrap_entry(entry, file_mime_type)
69
+ wrapped_entry = "--#{@boundary}\r\n"
70
+ wrapped_entry += "Content-Type: application/atom+xml\r\n\r\n"
71
+ wrapped_entry += entry
72
+ wrapped_entry += "\r\n--#{@boundary}\r\n"
73
+ wrapped_entry += "Content-Type: #{file_mime_type}\r\n\r\n"
74
+ return MimeBodyString.new(wrapped_entry)
75
+ end
76
+
77
+ end
78
+
79
+ # Class makes a string into a stream-like object
80
+ class MimeBodyString
81
+
82
+ def initialize(source_string)
83
+ @string = source_string
84
+ @bytes_read = 0
85
+ end
86
+
87
+ def rewind
88
+ @bytes_read = 0
89
+ end
90
+
91
+ # Implement read so that this class can be treated as a stream.
92
+ def read(bytes_requested)
93
+ if @bytes_read == @string.length
94
+ return false
95
+ elsif bytes_requested > @string.length - @bytes_read
96
+ bytes_requested = @string.length - @bytes_read
97
+ end
98
+
99
+ buffer = @string[@bytes_read, bytes_requested]
100
+ @bytes_read += bytes_requested
101
+
102
+ return buffer
103
+ end
104
+ end
105
+ end
106
+ 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
+