gdata 0.0.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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 rdoc
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
- Rake::RDocTask.new do |rd|
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.1'
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']
@@ -16,4 +16,7 @@ $:.unshift(File.dirname(__FILE__))
16
16
 
17
17
  require 'gdata/http'
18
18
  require 'gdata/client'
19
- require 'gdata/auth'
19
+ require 'gdata/auth'
20
+ # This is for Unicode "support"
21
+ require 'jcode'
22
+ $KCODE = 'UTF8'
@@ -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
- attr_accessor :private_key
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
- source = CGI.escape(source)
61
- password = CGI.escape(password)
62
- username = CGI.escape(username)
63
- body = "accountType=#{@account_type}&Email=#{username}" +
64
- "&Passwd=#{password}&service=#{@service}&source=#{source}"
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 += "&logintoken=#{login_token}&logincaptcha=#{login_captcha}"
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,
@@ -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/gdata'
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 parses the result with REXML.
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 + ' ' + response.body
97
+ raise UnknownError, "#{response.status_code} #{response.body}"
84
98
  end
85
99
 
86
- if response.body
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
- headers['Content-Type'] = 'application/atom+xml'
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