gdata 0.0.1 → 1.0.0
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.
- data/README +31 -5
- data/Rakefile +8 -8
- data/lib/gdata.rb +4 -1
- data/lib/gdata/auth/authsub.rb +1 -5
- data/lib/gdata/auth/clientlogin.rb +11 -11
- data/lib/gdata/client.rb +15 -1
- data/lib/gdata/client/apps.rb +27 -0
- data/lib/gdata/client/{gdata.rb → base.rb} +42 -26
- data/lib/gdata/client/blogger.rb +28 -0
- data/lib/gdata/client/booksearch.rb +28 -0
- data/lib/gdata/client/calendar.rb +28 -0
- data/lib/gdata/client/contacts.rb +28 -0
- data/lib/gdata/client/doclist.rb +28 -0
- data/lib/gdata/client/finance.rb +28 -0
- data/lib/gdata/client/gbase.rb +28 -0
- data/lib/gdata/client/gmail.rb +28 -0
- data/lib/gdata/client/health.rb +28 -0
- data/lib/gdata/client/notebook.rb +28 -0
- data/lib/gdata/client/photos.rb +29 -0
- data/lib/gdata/client/spreadsheets.rb +28 -0
- data/lib/gdata/client/webmaster_tools.rb +28 -0
- data/lib/gdata/client/youtube.rb +4 -7
- data/lib/gdata/http.rb +1 -0
- data/lib/gdata/http/default_service.rb +22 -4
- data/lib/gdata/http/mime_body.rb +95 -0
- data/lib/gdata/http/request.rb +5 -7
- data/lib/gdata/http/response.rb +13 -0
- data/test/tc_gdata_auth_clientlogin.rb +13 -0
- data/test/tc_gdata_client_base.rb +9 -1
- data/test/tc_gdata_client_photos.rb +65 -0
- data/test/tc_gdata_client_youtube.rb +5 -4
- data/test/tc_gdata_http_mime_body.rb +46 -0
- data/test/test_helper.rb +1 -1
- data/test/testimage.jpg +0 -0
- data/test/ts_gdata.rb +11 -0
- data/test/ts_gdata_client.rb +2 -0
- data/test/ts_gdata_http.rb +2 -0
- metadata +21 -3
data/README
CHANGED
@@ -9,10 +9,11 @@ Ruby wrapper for working with Google Data APIs
|
|
9
9
|
== SYNOPSIS:
|
10
10
|
|
11
11
|
yt = GData::Client::YouTube.new
|
12
|
+
yt.source = 'my_cool_application'
|
12
13
|
yt.clientlogin('username', 'password')
|
13
14
|
yt.client_id = 'CLIENT_ID'
|
14
15
|
yt.developer_key = 'DEVELOPER_KEY'
|
15
|
-
feed = yt.get('http://gdata.youtube.com/feeds/api/users/default/uploads')
|
16
|
+
feed = yt.get('http://gdata.youtube.com/feeds/api/users/default/uploads').to_xml
|
16
17
|
|
17
18
|
# creating, updating, and deleting a playlist
|
18
19
|
|
@@ -24,15 +25,40 @@ Ruby wrapper for working with Google Data APIs
|
|
24
25
|
</entry>
|
25
26
|
EOF
|
26
27
|
|
27
|
-
response = yt.post('http://gdata.youtube.com/feeds/api/users/default/playlists', entry)
|
28
|
+
response = yt.post('http://gdata.youtube.com/feeds/api/users/default/playlists', entry).to_xml
|
28
29
|
|
29
30
|
edit_uri = response.elements["link[@rel='edit']"].attributes['href']
|
30
31
|
|
31
32
|
response.elements["summary"].text = "Updated description"
|
32
33
|
|
33
|
-
response = yt.put(edit_uri, response.to_s)
|
34
|
+
response = yt.put(edit_uri, response.to_s).to_xml
|
34
35
|
|
35
|
-
yt.delete(edit_uri)
|
36
|
+
yt.delete(edit_uri).to_xml
|
37
|
+
|
38
|
+
# uploading a video
|
39
|
+
|
40
|
+
test_movie = '/path/to/a/movie.mov'
|
41
|
+
mime_type = 'video/quicktime'
|
42
|
+
feed = 'http://uploads.gdata.youtube.com/feeds/api/users/default/uploads'
|
43
|
+
|
44
|
+
entry = <<EOF
|
45
|
+
<entry xmlns="http://www.w3.org/2005/Atom"
|
46
|
+
xmlns:media="http://search.yahoo.com/mrss/"
|
47
|
+
xmlns:yt="http://gdata.youtube.com/schemas/2007">
|
48
|
+
<media:group>
|
49
|
+
<media:title type="plain">Test Movie</media:title>
|
50
|
+
<media:description type="plain">
|
51
|
+
This is a test with the Ruby library
|
52
|
+
</media:description>
|
53
|
+
<media:category
|
54
|
+
scheme="http://gdata.youtube.com/schemas/2007/categories.cat">People
|
55
|
+
</media:category>
|
56
|
+
<media:keywords>test,lame</media:keywords>
|
57
|
+
</media:group>
|
58
|
+
</entry>
|
59
|
+
EOF
|
60
|
+
|
61
|
+
response = @yt.post_file(feed, test_movie, mime_type, entry).to_xml
|
36
62
|
|
37
63
|
== REQUIREMENTS:
|
38
64
|
|
@@ -46,7 +72,7 @@ Tested against Ruby 1.8.6 patch level 114
|
|
46
72
|
|
47
73
|
To generate documentation:
|
48
74
|
|
49
|
-
rake
|
75
|
+
rake doc
|
50
76
|
|
51
77
|
To run unit tests:
|
52
78
|
|
data/Rakefile
CHANGED
@@ -15,15 +15,19 @@
|
|
15
15
|
require 'rubygems'
|
16
16
|
require 'rake/gempackagetask'
|
17
17
|
require 'rake/rdoctask'
|
18
|
+
require 'rake/testtask'
|
18
19
|
|
19
20
|
task :default => [:test]
|
20
|
-
task :doc => [:rdoc]
|
21
21
|
|
22
22
|
task :test do
|
23
23
|
ruby "test/ts_gdata.rb"
|
24
24
|
end
|
25
25
|
|
26
26
|
task :prepdoc do
|
27
|
+
all_doc_files = FileList.new('doc/**/*')
|
28
|
+
all_doc_files.each do |file|
|
29
|
+
system "svn add #{file}"
|
30
|
+
end
|
27
31
|
doc_files = FileList.new('doc/**/*.html')
|
28
32
|
doc_files.each do |file|
|
29
33
|
system "svn propset svn:mime-type 'text/html' #{file}"
|
@@ -34,14 +38,10 @@ task :prepdoc do
|
|
34
38
|
end
|
35
39
|
end
|
36
40
|
|
37
|
-
|
38
|
-
|
39
|
-
rd.main = 'README'
|
40
|
-
rd.rdoc_files.include('README', 'lib/**/*.rb')
|
41
|
-
rd.rdoc_dir = 'doc'
|
41
|
+
task :doc do
|
42
|
+
system "rdoc -U --title 'gdata module documentation' -m README README lib/"
|
42
43
|
end
|
43
44
|
|
44
|
-
|
45
45
|
spec = Gem::Specification.new do |s|
|
46
46
|
s.platform = Gem::Platform::RUBY
|
47
47
|
s.author = 'Jeff Fisher'
|
@@ -50,7 +50,7 @@ spec = Gem::Specification.new do |s|
|
|
50
50
|
s.summary = "Google Data APIs Ruby Utility Library"
|
51
51
|
s.rubyforge_project = 'gdata'
|
52
52
|
s.name = 'gdata'
|
53
|
-
s.version = '0.0
|
53
|
+
s.version = '1.0.0'
|
54
54
|
s.requirements << 'none'
|
55
55
|
s.require_path = 'lib'
|
56
56
|
s.test_files = FileList['test/ts_gdata.rb']
|
data/lib/gdata.rb
CHANGED
data/lib/gdata/auth/authsub.rb
CHANGED
@@ -23,9 +23,6 @@ module GData
|
|
23
23
|
# It can be used with a GData::Client::GData object.
|
24
24
|
class AuthSub
|
25
25
|
|
26
|
-
DEFAULT_OPTIONS = {
|
27
|
-
:private_key => nil }
|
28
|
-
|
29
26
|
# The URL of AuthSubRequest.
|
30
27
|
REQUEST_HANDLER = 'https://www.google.com/accounts/AuthSubRequest'
|
31
28
|
# The URL of AuthSubSessionToken.
|
@@ -40,7 +37,7 @@ module GData
|
|
40
37
|
# AuthSub access token.
|
41
38
|
attr_accessor :token
|
42
39
|
# Private RSA key used to sign secure requests.
|
43
|
-
|
40
|
+
attr_reader :private_key
|
44
41
|
|
45
42
|
# Initialize the class with a new token. Optionally pass a private
|
46
43
|
# key or custom URLs.
|
@@ -53,7 +50,6 @@ module GData
|
|
53
50
|
|
54
51
|
@token = token
|
55
52
|
|
56
|
-
options = DEFAULT_OPTIONS.merge(options)
|
57
53
|
options.each do |key, value|
|
58
54
|
self.send("#{key}=", value)
|
59
55
|
end
|
@@ -21,10 +21,6 @@ module GData
|
|
21
21
|
# It can be used with a GData::Client::GData object.
|
22
22
|
class ClientLogin
|
23
23
|
|
24
|
-
DEFAULT_OPTIONS = {
|
25
|
-
:auth_url => 'https://www.google.com/accounts/ClientLogin',
|
26
|
-
:account_type => 'HOSTED_OR_GOOGLE' }
|
27
|
-
|
28
24
|
# The ClientLogin authentication handler
|
29
25
|
attr_accessor :auth_url
|
30
26
|
# One of 'HOSTED_OR_GOOGLE', 'GOOGLE', or 'HOSTED'.
|
@@ -45,10 +41,12 @@ module GData
|
|
45
41
|
|
46
42
|
@service = service
|
47
43
|
|
48
|
-
options = DEFAULT_OPTIONS.merge(options)
|
49
44
|
options.each do |key, value|
|
50
45
|
self.send("#{key}=", value)
|
51
46
|
end
|
47
|
+
|
48
|
+
@auth_url ||= 'https://www.google.com/accounts/ClientLogin'
|
49
|
+
@account_type ||= 'HOSTED_OR_GOOGLE'
|
52
50
|
end
|
53
51
|
|
54
52
|
# Retrieves a token for the given username and password.
|
@@ -57,13 +55,15 @@ module GData
|
|
57
55
|
# to a previously issued CAPTCHA challenge.
|
58
56
|
def get_token(username, password, source, login_token = nil,
|
59
57
|
login_captcha = nil)
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
body =
|
64
|
-
|
58
|
+
body = Hash.new
|
59
|
+
body['accountType'] = @account_type
|
60
|
+
body['Email'] = username
|
61
|
+
body['Passwd'] = password
|
62
|
+
body['service'] = @service
|
63
|
+
body['source'] = source
|
65
64
|
if login_token and login_captcha
|
66
|
-
body
|
65
|
+
body['logintoken'] = login_token
|
66
|
+
body['logincaptcha'] = login_captcha
|
67
67
|
end
|
68
68
|
|
69
69
|
request = GData::HTTP::Request.new(@auth_url, :body => body,
|
data/lib/gdata/client.rb
CHANGED
@@ -12,7 +12,21 @@
|
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
|
-
require 'gdata/client/
|
15
|
+
require 'gdata/client/base'
|
16
|
+
require 'gdata/client/apps'
|
17
|
+
require 'gdata/client/blogger'
|
18
|
+
require 'gdata/client/booksearch'
|
19
|
+
require 'gdata/client/calendar'
|
20
|
+
require 'gdata/client/contacts'
|
21
|
+
require 'gdata/client/doclist'
|
22
|
+
require 'gdata/client/finance'
|
23
|
+
require 'gdata/client/gbase'
|
24
|
+
require 'gdata/client/gmail'
|
25
|
+
require 'gdata/client/health'
|
26
|
+
require 'gdata/client/notebook'
|
27
|
+
require 'gdata/client/photos'
|
28
|
+
require 'gdata/client/spreadsheets'
|
29
|
+
require 'gdata/client/webmaster_tools'
|
16
30
|
require 'gdata/client/youtube'
|
17
31
|
|
18
32
|
module GData
|
@@ -0,0 +1,27 @@
|
|
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
|
+
module GData
|
16
|
+
module Client
|
17
|
+
|
18
|
+
# Client class to wrap working with the Apps Provisioning API.
|
19
|
+
class Apps < Base
|
20
|
+
|
21
|
+
def initialize(options = {})
|
22
|
+
options[:clientlogin_service] ||= 'apps'
|
23
|
+
super(options)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -19,16 +19,6 @@ module GData
|
|
19
19
|
|
20
20
|
# A client object used to interact with different Google Data APIs.
|
21
21
|
class Base
|
22
|
-
|
23
|
-
DEFAULT_OPTIONS = {
|
24
|
-
:auth_handler => nil,
|
25
|
-
:http_service => GData::HTTP::DefaultService,
|
26
|
-
:version => "2",
|
27
|
-
:clientlogin_url => nil,
|
28
|
-
:clientlogin_service => nil,
|
29
|
-
:authsub_scope => nil,
|
30
|
-
:headers => {},
|
31
|
-
:source => 'AnonymousApp' }
|
32
22
|
|
33
23
|
# A subclass of GData::Auth that handles authentication signing.
|
34
24
|
attr_accessor :auth_handler
|
@@ -49,13 +39,37 @@ module GData
|
|
49
39
|
attr_accessor :source
|
50
40
|
|
51
41
|
def initialize(options = {})
|
52
|
-
options = DEFAULT_OPTIONS.merge(options)
|
53
42
|
options.each do |key, value|
|
54
43
|
self.send("#{key}=", value)
|
55
44
|
end
|
45
|
+
|
46
|
+
@headers ||= {}
|
47
|
+
@http_service ||= GData::HTTP::DefaultService
|
48
|
+
@version ||= '2'
|
49
|
+
@source ||= 'AnonymousApp'
|
50
|
+
end
|
51
|
+
|
52
|
+
# Sends an HTTP request with the given file as a stream
|
53
|
+
def make_file_request(method, url, file_path, mime_type, entry = nil)
|
54
|
+
if not File.readable?(file_path)
|
55
|
+
raise ArgumentError, "File #{file_path} is not readable."
|
56
|
+
end
|
57
|
+
file = File.open(file_path, 'rb')
|
58
|
+
@headers['Slug'] = File.basename(file_path)
|
59
|
+
if entry
|
60
|
+
@headers['MIME-Version'] = '1.0'
|
61
|
+
body = GData::HTTP::MimeBody.new(entry, file, mime_type)
|
62
|
+
@headers['Content-Type'] = body.content_type
|
63
|
+
response = self.make_request(method, url, body)
|
64
|
+
else
|
65
|
+
@headers['Content-Type'] = mime_type
|
66
|
+
response = self.make_request(method, url, file)
|
67
|
+
end
|
68
|
+
file.close
|
69
|
+
return response
|
56
70
|
end
|
57
71
|
|
58
|
-
# Sends an HTTP request and
|
72
|
+
# Sends an HTTP request and return the response.
|
59
73
|
def make_request(method, url, body = '')
|
60
74
|
headers = self.prepare_headers
|
61
75
|
request = GData::HTTP::Request.new(url, :headers => headers,
|
@@ -80,21 +94,10 @@ module GData
|
|
80
94
|
when 500
|
81
95
|
raise ServerError, response.body
|
82
96
|
else
|
83
|
-
raise UnknownError, response.status_code
|
97
|
+
raise UnknownError, "#{response.status_code} #{response.body}"
|
84
98
|
end
|
85
99
|
|
86
|
-
|
87
|
-
begin
|
88
|
-
document = REXML::Document.new(response.body).root
|
89
|
-
if document.nil?
|
90
|
-
return response.body
|
91
|
-
else
|
92
|
-
return document
|
93
|
-
end
|
94
|
-
rescue
|
95
|
-
return response.body
|
96
|
-
end
|
97
|
-
end
|
100
|
+
return response
|
98
101
|
end
|
99
102
|
|
100
103
|
# Performs an HTTP GET against the API.
|
@@ -107,11 +110,21 @@ module GData
|
|
107
110
|
return self.make_request(:put, url, body)
|
108
111
|
end
|
109
112
|
|
113
|
+
# Performs an HTTP PUT with the given file
|
114
|
+
def put_file(url, file_path, mime_type, entry = nil)
|
115
|
+
return self.make_file_request(:put, url, file_path, mime_type, entry)
|
116
|
+
end
|
117
|
+
|
110
118
|
# Performs an HTTP POST against the API.
|
111
119
|
def post(url, body)
|
112
120
|
return self.make_request(:post, url, body)
|
113
121
|
end
|
114
122
|
|
123
|
+
# Performs an HTTP POST with the given file
|
124
|
+
def post_file(url, file_path, mime_type, entry = nil)
|
125
|
+
return self.make_file_request(:post, url, file_path, mime_type, entry)
|
126
|
+
end
|
127
|
+
|
115
128
|
# Performs an HTTP DELETE against the API.
|
116
129
|
def delete(url)
|
117
130
|
return self.make_request(:delete, url)
|
@@ -122,7 +135,10 @@ module GData
|
|
122
135
|
headers = @headers
|
123
136
|
headers['GData-Version'] = @version
|
124
137
|
headers['User-Agent'] = GData::Auth::SOURCE_LIB_STRING + @source
|
125
|
-
|
138
|
+
# by default we assume we are sending Atom entries
|
139
|
+
if not headers.has_key?('Content-Type')
|
140
|
+
headers['Content-Type'] = 'application/atom+xml'
|
141
|
+
end
|
126
142
|
return headers
|
127
143
|
end
|
128
144
|
|
@@ -0,0 +1,28 @@
|
|
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
|
+
module GData
|
16
|
+
module Client
|
17
|
+
|
18
|
+
# Client class to wrap working with the Blogger API.
|
19
|
+
class Blogger < Base
|
20
|
+
|
21
|
+
def initialize(options = {})
|
22
|
+
options[:clientlogin_service] ||= 'blogger'
|
23
|
+
options[:authsub_scope] ||= 'http://www.blogger.com/feeds/'
|
24
|
+
super(options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
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
|
+
module GData
|
16
|
+
module Client
|
17
|
+
|
18
|
+
# Client class to wrap working with the Book Search Data API.
|
19
|
+
class BookSearch < Base
|
20
|
+
|
21
|
+
def initialize(options = {})
|
22
|
+
options[:clientlogin_service] ||= 'print'
|
23
|
+
options[:authsub_scope] ||= 'http://www.google.com/books/feeds/'
|
24
|
+
super(options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,28 @@
|
|
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
|
+
module GData
|
16
|
+
module Client
|
17
|
+
|
18
|
+
# Client class to wrap working with the Calendar Data API.
|
19
|
+
class Calendar < Base
|
20
|
+
|
21
|
+
def initialize(options = {})
|
22
|
+
options[:clientlogin_service] ||= 'cl'
|
23
|
+
options[:authsub_scope] ||= 'http://www.google.com/calendar/feeds/'
|
24
|
+
super(options)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|