GoogleReaderApi 0.3.5 → 0.3.6

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.
@@ -1,44 +1,42 @@
1
1
  # Generated by jeweler
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
- # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{GoogleReaderApi}
8
- s.version = "0.3.5"
8
+ s.version = "0.3.6"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
- s.authors = ["Toon Willems"]
12
- s.date = %q{2010-06-22}
11
+ s.authors = [%q{Toon Willems}]
12
+ s.date = %q{2011-08-21}
13
13
  s.description = %q{a google reader api (unofficial) written in ruby}
14
14
  s.email = %q{willemstoon@gmail.com}
15
15
  s.extra_rdoc_files = [
16
16
  "README.mdown"
17
17
  ]
18
18
  s.files = [
19
- ".gitignore",
20
- "GoogleReaderApi.gemspec",
21
- "License",
22
- "README.mdown",
23
- "Rakefile",
24
- "VERSION",
25
- "lib/google-reader-api/api.rb",
26
- "lib/google-reader-api/cache.rb",
27
- "lib/google-reader-api/entry.rb",
28
- "lib/google-reader-api/feed.rb",
29
- "lib/google-reader-api/rss_utils.rb",
30
- "lib/google-reader-api/subscription_list.rb",
31
- "lib/google-reader-api/user.rb",
32
- "lib/google_reader_api.rb"
19
+ "GoogleReaderApi.gemspec",
20
+ "License",
21
+ "README.mdown",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "lib/google-reader-api/api.rb",
25
+ "lib/google-reader-api/cache.rb",
26
+ "lib/google-reader-api/entry.rb",
27
+ "lib/google-reader-api/feed.rb",
28
+ "lib/google-reader-api/google_login.rb",
29
+ "lib/google-reader-api/rss_utils.rb",
30
+ "lib/google-reader-api/subscription_list.rb",
31
+ "lib/google-reader-api/user.rb",
32
+ "lib/google_reader_api.rb"
33
33
  ]
34
34
  s.homepage = %q{http://github.com/nudded/GoogleReaderAPI}
35
- s.rdoc_options = ["--charset=UTF-8"]
36
- s.require_paths = ["lib"]
37
- s.rubygems_version = %q{1.3.7}
35
+ s.require_paths = [%q{lib}]
36
+ s.rubygems_version = %q{1.8.8}
38
37
  s.summary = %q{a google reader api (unofficial) written in ruby}
39
38
 
40
39
  if s.respond_to? :specification_version then
41
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
42
40
  s.specification_version = 3
43
41
 
44
42
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.5
1
+ 0.3.6
@@ -1,41 +1,52 @@
1
1
  module GoogleReaderApi
2
-
2
+
3
3
  class Api
4
-
4
+
5
5
  require "cgi"
6
6
  require "net/https"
7
7
  require "uri"
8
-
8
+
9
9
  BASE_URL = "http://www.google.com/reader/"
10
-
11
- def initialize(email,password)
12
- request_sid(email,password)
10
+
11
+ # specify either the :email and :password or the :auth token you got in the past
12
+ #
13
+ # [:email] the user's email address for login purposes
14
+ #
15
+ # [:password] the user's password for login purposes
16
+ #
17
+ # [:auth] the auth token you got from a previous authentication request
18
+ # if you provide this you do not need to provide the email and password
19
+ def initialize(options)
20
+ if options[:auth]
21
+ @auth = options[:auth]
22
+ else
23
+ request_auth(options[:email],options[:password])
24
+ end
13
25
  @cache = GoogleReaderApi::Cache.new(2)
14
26
  end
15
-
27
+
16
28
  # do a get request to the link
17
29
  # args is a hash of values that should be used in the request
18
30
  def get_link(link,args={})
19
31
  link = BASE_URL + link
20
32
  get_request(link,args)
21
33
  end
22
-
34
+
23
35
  def post_link(link,args={})
24
36
  link = BASE_URL + link
25
37
  post_request(link,args)
26
38
  end
27
-
39
+
28
40
  def cached_unread_count
29
41
  @cache['unread-count'] ||= get_link 'api/0/unread-count', :output => :json
30
42
  end
31
-
43
+
32
44
  private
33
45
 
34
46
  # url as a string
35
47
  # the post data as a hash
36
48
  def post_request(url,args)
37
49
  uri = URI.parse(url)
38
- args[:T] = token
39
50
  req = Net::HTTP::Post.new(uri.path)
40
51
  req.set_form_data(args)
41
52
  request(uri,req)
@@ -45,24 +56,24 @@ module GoogleReaderApi
45
56
  # e.g. :allcomments => true etc...
46
57
  def get_request(url,args)
47
58
  uri = URI.parse url
48
-
59
+
49
60
  # ck is the current unix timestamp
50
61
  args[:ck] = Time.now.to_i unless args[:ck]
51
-
62
+
52
63
  req = Net::HTTP::Get.new("#{uri.path}?#{argument_string(args)}")
53
64
  request(uri,req)
54
65
  end
55
66
 
56
67
  def request(uri,request)
57
68
  # add the cookie to the http header
58
- request.add_field('Cookie',user_cookie)
69
+ request.add_field('Authorization',"GoogleLogin auth=#{auth}")
59
70
  res = Net::HTTP.start(uri.host,uri.port) do |http|
60
71
  http.request(request)
61
72
  end
62
73
  # TODO: use better exception
63
74
  if res.code != '200'
64
75
  p res.body
65
- raise "something went wrong"
76
+ raise "something went wrong"
66
77
  end
67
78
  res.body
68
79
  end
@@ -71,37 +82,17 @@ module GoogleReaderApi
71
82
  def argument_string(args)
72
83
  args.to_a.map { |v| v.join '=' }.join('&')
73
84
  end
74
-
75
- def token
76
- url = URI.parse "http://www.google.com/reader/api/0/token"
77
- res = Net::HTTP.start(url.host,url.port) do |http|
78
- http.get(url.path,"Cookie" => user_cookie)
79
- end
80
- res.body
81
- end
82
85
 
83
- def user_cookie
84
- CGI::Cookie::new('name' => 'SID' , 'value' => sid ,
85
- 'path' => '/' , 'domain' => '.google.com').to_s
86
+ def auth
87
+ @auth
86
88
  end
87
89
 
88
- def sid
89
- @sid
90
- end
91
-
92
- def request_sid(email,password)
93
- password = CGI.escape(password)
94
- email = CGI.escape(email)
95
- url = URI.parse "https://www.google.com/accounts/ClientLogin?service=reader&Email=#{email}&Passwd=#{password}"
96
- http = Net::HTTP.new(url.host,url.port)
97
- http.use_ssl = true
98
- res,data = http.get("#{url.path}?#{url.query}")
99
-
100
- raise "could not authenticate" if res.code != "200"
101
-
102
- @sid = data.match(/SID=(.+?)\n/)[1]
90
+ def request_auth(email,password)
91
+ login = GoogleLogin::ClientLogin.new :service => 'reader', :source => 'nudded-greader-0.1'
92
+ login.authenticate email, password
93
+ @auth = login.auth
103
94
  end
104
-
95
+
105
96
  end
106
-
107
- end
97
+
98
+ end
@@ -0,0 +1,139 @@
1
+ require "net/https"
2
+ require "uri"
3
+
4
+ module GoogleLogin
5
+
6
+ # == ClientLogin
7
+ #
8
+ # Use this Class to get an auth-token
9
+ class ClientLogin
10
+
11
+ # Base Exception class
12
+ LoginError = Class.new Exception
13
+
14
+ # All the possible exceptions
15
+ [
16
+ "BadAuthentication",
17
+ "NotVerified",
18
+ "TermsNotAgreed",
19
+ "CaptchaRequired",
20
+ "Unknown",
21
+ "AccountDeleted",
22
+ "AccountDisabled",
23
+ "ServiceDisabled",
24
+ "ServiceUnavailable",
25
+ ].each do |const|
26
+ const_set const, Class.new(LoginError)
27
+ end
28
+
29
+ DEFAULTS = {
30
+ :accountType => 'HOSTED_OR_GOOGLE' ,
31
+ :source => 'companyName-applicationName-versionID',
32
+ :service => 'service-identifier'
33
+ }
34
+
35
+ attr_reader :auth, :sid, :lsid, :captcha_url
36
+
37
+ # specify the :service, :source and optionally :accountType
38
+ #
39
+ # [:service] the service identifier, check the google api documentation.
40
+ #
41
+ # [:source] the name of your application. String should be in the form
42
+ # "companyName-applicationName-versionID".
43
+ #
44
+ # [:accountType] one of the following values:
45
+ # "GOOGLE", "HOSTED", "HOSTED_OR_GOOGLE" (default if none
46
+ # given)
47
+ def initialize(arghash = {})
48
+ @options = DEFAULTS.merge arghash
49
+ end
50
+
51
+ # authenticate a user, which sets the auth, sid and lsid instance_variables
52
+ # if you provide a block, it will be called with a captcha url if google
53
+ # forces you to answer the captcha. Make sure you return the anwer in the block.
54
+ #
55
+ # if no block is given, this will raise a CaptchaRequired error.
56
+ # you can rescue them and show the url via the captcha_url method.
57
+ #
58
+ # you can then call authenticate and as 3rd parameter you provide the
59
+ # captcha answer.
60
+ #
61
+ # all Exceptions this raises are subclasses of ClientLogin::LoginError.
62
+ # so make sure you handle them.
63
+ #
64
+ # This is a list of all the possible errors and their meaning
65
+ # Error code:: Description
66
+ # BadAuthentication:: The login request used a username or password that is not recognized.
67
+ # NotVerified:: The account email address has not been verified. The user will need to access their Google account directly to resolve the issue before logging in using a non-Google application.
68
+ # TermsNotAgreed:: The user has not agreed to terms. The user will need to access their Google account directly to resolve the issue before logging in using a non-Google application.
69
+ # CaptchaRequired:: A CAPTCHA is required. (A response with this error code will also contain an image URL and a CAPTCHA token.)
70
+ # Unknown:: The error is unknown or unspecified; the request contained invalid input or was malformed.
71
+ # AccountDeleted:: The user account has been deleted.
72
+ # AccountDisabled:: The user account has been disabled.
73
+ # ServiceDisabled:: The user's access to the specified service has been disabled. (The user account may still be valid.)
74
+ # ServiceUnavailable:: The service is not available; try again later.
75
+ def authenticate(username, password, captcha_response = nil)
76
+ @options[:Email], @options[:Passwd] = username, password
77
+ # set logincaptcha, captchatoken will already be set
78
+ @options[:logincaptcha] = captcha_response if captcha_response
79
+
80
+ parse_response perform_request
81
+
82
+ rescue CaptchaRequired
83
+ if block_given?
84
+ @options[:logincaptcha] = yield captcha_url
85
+ retry
86
+ else
87
+ raise CaptchaRequired
88
+ end
89
+ end
90
+
91
+ private
92
+
93
+ def perform_request
94
+ request = Net::HTTP::Post.new '/accounts/ClientLogin'
95
+ request.form_data = @options
96
+
97
+ https = Net::HTTP.new 'www.google.com', 443
98
+ https.use_ssl = true
99
+
100
+ https.request request
101
+ end
102
+
103
+ def parse_body(response_body)
104
+ response_body.scan(/(\w+)=(.+)\n/).each do |key, value|
105
+ instance_variable_set "@#{key.downcase}" , value
106
+ end
107
+ end
108
+
109
+ def parse_response(response)
110
+ if response.code_type == Net::HTTPOK
111
+ parse_body response.body
112
+ else
113
+ handle_error response.body
114
+ end
115
+ end
116
+
117
+
118
+ def handle_error(response_body)
119
+ error_message = response_body.match(/Error=(\w+)\n/)[1].strip
120
+
121
+ if error_message == "CaptchaRequired"
122
+ @options[:logintoken] = response_body.match(/CaptchaToken=(.+)\n/)[1]
123
+ self.captcha_url = response_body.match(/CaptchaUrl=(.+)\n/)[1]
124
+ end
125
+
126
+ raise_error_class error_message
127
+ end
128
+
129
+ def raise_error_class(error_message)
130
+ raise self.class.const_get error_message
131
+ end
132
+
133
+ def captcha_url=(url)
134
+ @captcha_url = "http://www.google.com/accounts/" << url
135
+ end
136
+
137
+ end
138
+
139
+ end
@@ -5,9 +5,17 @@ module GoogleReaderApi
5
5
  require "json"
6
6
  # maybe someone would like to access the api for a user
7
7
  attr_reader :api
8
-
9
- def initialize(email,password)
10
- @api = GoogleReaderApi::Api::new email,password
8
+
9
+ # specify either the :email and :password or the :auth token you got in the past
10
+ #
11
+ # [:email] the user's email address for login purposes
12
+ #
13
+ # [:password] the user's password for login purposes
14
+ #
15
+ # [:auth] the auth token you got from a previous authentication request
16
+ # if you provide this you do not need to provide the email and password
17
+ def initialize(options)
18
+ @api = GoogleReaderApi::Api::new options
11
19
  end
12
20
 
13
21
  def info
@@ -4,4 +4,5 @@ require "google-reader-api/cache"
4
4
  require "google-reader-api/entry"
5
5
  require "google-reader-api/feed"
6
6
  require "google-reader-api/subscription_list"
7
- require "google-reader-api/user"
7
+ require "google-reader-api/user"
8
+ require "google-reader-api/google_login"
metadata CHANGED
@@ -1,34 +1,23 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: GoogleReaderApi
3
- version: !ruby/object:Gem::Version
4
- hash: 25
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 3
9
- - 5
10
- version: 0.3.5
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.6
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Toon Willems
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2010-06-22 00:00:00 +02:00
19
- default_executable:
12
+ date: 2011-08-21 00:00:00.000000000Z
20
13
  dependencies: []
21
-
22
14
  description: a google reader api (unofficial) written in ruby
23
15
  email: willemstoon@gmail.com
24
16
  executables: []
25
-
26
17
  extensions: []
27
-
28
- extra_rdoc_files:
18
+ extra_rdoc_files:
29
19
  - README.mdown
30
- files:
31
- - .gitignore
20
+ files:
32
21
  - GoogleReaderApi.gemspec
33
22
  - License
34
23
  - README.mdown
@@ -38,43 +27,33 @@ files:
38
27
  - lib/google-reader-api/cache.rb
39
28
  - lib/google-reader-api/entry.rb
40
29
  - lib/google-reader-api/feed.rb
30
+ - lib/google-reader-api/google_login.rb
41
31
  - lib/google-reader-api/rss_utils.rb
42
32
  - lib/google-reader-api/subscription_list.rb
43
33
  - lib/google-reader-api/user.rb
44
34
  - lib/google_reader_api.rb
45
- has_rdoc: true
46
35
  homepage: http://github.com/nudded/GoogleReaderAPI
47
36
  licenses: []
48
-
49
37
  post_install_message:
50
- rdoc_options:
51
- - --charset=UTF-8
52
- require_paths:
38
+ rdoc_options: []
39
+ require_paths:
53
40
  - lib
54
- required_ruby_version: !ruby/object:Gem::Requirement
41
+ required_ruby_version: !ruby/object:Gem::Requirement
55
42
  none: false
56
- requirements:
57
- - - ">="
58
- - !ruby/object:Gem::Version
59
- hash: 3
60
- segments:
61
- - 0
62
- version: "0"
63
- required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
48
  none: false
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- hash: 3
69
- segments:
70
- - 0
71
- version: "0"
49
+ requirements:
50
+ - - ! '>='
51
+ - !ruby/object:Gem::Version
52
+ version: '0'
72
53
  requirements: []
73
-
74
54
  rubyforge_project:
75
- rubygems_version: 1.3.7
55
+ rubygems_version: 1.8.8
76
56
  signing_key:
77
57
  specification_version: 3
78
58
  summary: a google reader api (unofficial) written in ruby
79
59
  test_files: []
80
-
data/.gitignore DELETED
@@ -1 +0,0 @@
1
- pkg