diandian-oauth 0.0.3 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -3,3 +3,4 @@ source 'http://rubygems.org'
3
3
  gem 'oauth2', '~> 0.8.0'
4
4
  gem 'activemodel', '~> 3.2.6'
5
5
  gem 'activesupport', ' ~> 3.2.1'
6
+ gem 'faraday', :git => "https://github.com/secretworry/faraday.git"
@@ -1,3 +1,10 @@
1
+ GIT
2
+ remote: https://github.com/secretworry/faraday.git
3
+ revision: b34ecbb6cd4d0b2280cdb19a15f1d39a9b0eb309
4
+ specs:
5
+ faraday (0.8.0)
6
+ multipart-post (~> 1.1)
7
+
1
8
  GEM
2
9
  remote: http://rubygems.org/
3
10
  specs:
@@ -8,8 +15,6 @@ GEM
8
15
  i18n (~> 0.6)
9
16
  multi_json (~> 1.0)
10
17
  builder (3.0.0)
11
- faraday (0.8.1)
12
- multipart-post (~> 1.1)
13
18
  httpauth (0.1)
14
19
  i18n (0.6.0)
15
20
  jwt (0.1.5)
@@ -30,4 +35,5 @@ PLATFORMS
30
35
  DEPENDENCIES
31
36
  activemodel (~> 3.2.6)
32
37
  activesupport (~> 3.2.1)
38
+ faraday!
33
39
  oauth2 (~> 0.8.0)
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'diandian-oauth'
3
- s.version = '0.0.3'
3
+ s.version = '0.1.1'
4
4
  s.date = '2012-07-24'
5
5
  s.summary = "Client for diandian API"
6
6
  s.description = "A Ruby Client for diandian API"
@@ -1,10 +1,11 @@
1
+ require 'active_support/core_ext'
1
2
  require 'diandian_oauth/api'
2
3
  require 'diandian_oauth/client'
3
4
  require 'diandian_oauth/exceptions'
4
- require 'active_support/core_ext'
5
+ require 'diandian_oauth/models/response'
5
6
  require 'logger'
6
7
  module DiandianOAuth
7
- VERSION = '0.0.3'
8
+ VERSION = '0.1.1'
8
9
  module Logger
9
10
  def logger *args
10
11
  if args.empty?
@@ -16,4 +17,4 @@ module DiandianOAuth
16
17
  end
17
18
  extend Logger
18
19
  logger STDOUT
19
- end
20
+ end
@@ -18,15 +18,22 @@ module DiandianOAuth
18
18
  interface :user_likes, Interface::UserLikes
19
19
  interface :user_followings, Interface::UserFollowings
20
20
  interface :my_tags, Interface::MyTags
21
- interface :blog, Interface::Blog
22
21
  interface :blog_info, Interface::BlogInfo
23
22
  interface :blog_avatar, Interface::BlogAvatar
24
23
  interface :blog_followers, Interface::BlogFollowers
25
24
  interface :posts, Interface::Posts
25
+ interface :post_info, Interface::PostInfo
26
+ interface :create_post, Interface::CreatePost
27
+ interface :delete_post, Interface::DeletePost
28
+ interface :reblog_post, Interface::ReblogPost
26
29
  interface :home_feeds, Interface::HomeFeeds
27
30
  interface :tag_feeds, Interface::TagFeeds
28
31
  interface :follow, Interface::Follow
29
32
  interface :unfollow, Interface::Unfollow
33
+ interface :watch_tag, Interface::WatchTag
34
+ interface :unwatch_tag, Interface::UnwatchTag
30
35
  interface :submissions, Interface::Submissions
36
+ interface :submit, Interface::Submit
37
+ interface :reject_submission, Interface::RejectSubmission
31
38
  end
32
39
  end
@@ -1,4 +1,3 @@
1
-
2
1
  module DiandianOAuth
3
2
  class API
4
3
  module Interface
@@ -40,20 +39,43 @@ module DiandianOAuth
40
39
  end
41
40
  end #Param
42
41
 
42
+ class Params
43
+ def initialize(params = {})
44
+ @params = params.symbolize_keys!
45
+ end
46
+ def [] key
47
+ @params[key.to_sym]
48
+ end
49
+
50
+ def []= key, value
51
+ @params[key.to_sym] = value
52
+ end
53
+
54
+ def to_a
55
+ @params.reduce([]) do |all, (key, value)|
56
+ case value
57
+ when Array
58
+ value.each{|v| all << [key, v]}
59
+ else
60
+ all << [key, value]
61
+ end
62
+ all
63
+ end
64
+ end
65
+
66
+ def to_h
67
+ @params
68
+ end
69
+ end
70
+
43
71
  class Base
44
72
  def request_url params = {}
45
73
  raise 'subclasses must implement this method'
46
74
  end
47
75
 
48
- # when the access_token is out-of-date, refresh it automatically
49
- def apply! access_token, params, &block
50
- access_token.refresh! if access_token.expired?
51
- self.apply access_token, params, &block
52
- end
53
-
54
76
  def apply access_token, params, &block
55
- raise TokenExpiredException if access_token.expired?
56
- params ||= {}
77
+ raise TokenExpiredError if access_token.expired?
78
+ params = Params.new( params || {})
57
79
  action = case request_verb
58
80
  when /get/ then :get
59
81
  when /post/ then :post
@@ -62,30 +84,27 @@ module DiandianOAuth
62
84
  else raise "unrecognized verb '#{request_verb}'"
63
85
  end # case
64
86
  options = {
65
- :params => extract_params(params),
87
+ :body => extract_params(params).to_a,
66
88
  :raise_errors => false,
67
89
  :parse => :json
68
90
  }
69
91
  request_url = self.request_url(params)
70
92
  if DiandianOAuth.logger.debug?
71
- DiandianOAuth.logger.debug("request with action:'#{action}', request_url:'#{request_url}'")
93
+ DiandianOAuth.logger.debug("request with action:'#{action}', request_url:'#{request_url}', options:'#{options}'")
72
94
  end
73
- access_token.request( action, request_url, options, &block)
95
+ DiandianOAuth::Response.from_response access_token.request( action, request_url, options, &block)
74
96
  end
75
97
  protected
76
98
  def request_verb
77
99
  self.class.verb
78
100
  end
79
101
  def extract_params params
80
- params.symbolize_keys!
81
- self.class.params.each_pair.reduce({}) do |result, ele|
82
- key = ele[0]
83
- param = ele[1]
102
+ self.class.params.reduce(Params.new) do |result, (key, value)|
84
103
  param_value = params[key]
85
- if param_value && param.required
104
+ if param_value
86
105
  result[key] = param_value
87
- elsif param.required
88
- raise ParamIsRequiredException.new( "'#{key}' is required")
106
+ elsif value.required
107
+ raise ParamIsRequiredError.new( "'#{key}' is required")
89
108
  end
90
109
  result
91
110
  end
@@ -137,8 +156,9 @@ module DiandianOAuth
137
156
  protected
138
157
  def blog_request_url params
139
158
  blog_cname = params[:blogCName]
140
- raise ParamIsRequiredException.new("blogCName is required for interface #{self.class.name}") unless blog_cname
141
- API.url_for "/blog/#{blog_cname}"
159
+ blog_uuid = params[:blogUuid]
160
+ raise ParamIsRequiredError.new("blogCName or blogUuid is required for interface #{self.class.name}") unless blog_cname || blog_uuid
161
+ API.url_for "/blog/#{blog_cname||blog_uuid}"
142
162
  end
143
163
  end #BlogInterface
144
164
 
@@ -155,7 +175,7 @@ module DiandianOAuth
155
175
  size = params[:size]
156
176
  if size
157
177
  unless BlogAvatar.is_valid_size size
158
- raise IllegalParamException.new("'#{size}' is illegal")
178
+ raise IllegalParamError.new("'#{size}' is illegal")
159
179
  end
160
180
  end # if
161
181
  end
@@ -166,13 +186,24 @@ module DiandianOAuth
166
186
 
167
187
  end #BlogAvatar
168
188
 
189
+ class PostInfo < Base
190
+ param :id, :required => true
191
+ def request_url params={}
192
+ blog_cname = params[:blogCName]
193
+ blog_uuid = params[:blogUuid]
194
+ raise ParamIsRequiredError.new("blogCName or blogUuid is required for interface #{self.class.name}") unless blog_cname || blog_uuid
195
+ API.url_for "/blog/#{blog_cname || blog_uuid}/posts"
196
+ end
197
+ end
198
+
169
199
  class BlogFollowers < Base
170
200
  param :limit, :required => false
171
201
  param :offset, :required => false
172
202
  def request_url params={}
173
203
  blog_cname = params[:blogCName]
174
- raise ParamIsRequiredException.new("blogCName is required for interface #{self.class.name}") unless blog_cname
175
- API.url_for "/blog/#{blog_cname}/info"
204
+ blog_uuid = params[:blogUuid]
205
+ raise ParamIsRequiredError.new("blogCName or blogUuid is required for interface #{self.class.name}") unless blog_cname || blog_uuid
206
+ API.url_for "/blog/#{blog_cname || blog_uuid}/info"
176
207
  end
177
208
  end #BlogFollowers
178
209
 
@@ -186,8 +217,9 @@ module DiandianOAuth
186
217
  param :filter, :required => false
187
218
  def request_url params={}
188
219
  blog_cname = params[:blogCName]
189
- raise ParamIsRequiredException.new("blogCName is required for interface #{self.class.name}") unless blog_cname
190
- path = "/blog/#{blog_cname}/posts"
220
+ blog_uuid = params[:blogUuid]
221
+ raise ParamIsRequiredError.new("blogCName or blogUuid is required for interface #{self.class.name}") unless blog_cname || blog_uuid
222
+ path = "/blog/#{blog_cname||blog_uuid}/posts"
191
223
  if params[:type]
192
224
  path = path + "/#{type}"
193
225
  end
@@ -195,6 +227,107 @@ module DiandianOAuth
195
227
  end
196
228
  end # Posts
197
229
 
230
+ class CreatePost < Base
231
+ verb :post
232
+ param :type, :required => true
233
+ param :state, :required => true
234
+ param :tag, :required => false
235
+ param :slug, :required => false
236
+ #text
237
+ param :title, :required => false
238
+ param :body, :required => false
239
+ #photo
240
+ param :caption, :required => false
241
+ param :layout, :required => false
242
+ param :data, :required => false
243
+ param :itemDesc, :required => false
244
+ #link
245
+ param :title, :required => false
246
+ param :url, :required => false
247
+ param :description, :required => false
248
+
249
+ #audio
250
+ param :caption, :required => false
251
+ param :data, :required => false
252
+ param :musicName, :required => false
253
+ param :musicSinger, :required => false
254
+ param :albumName, :required => false
255
+
256
+ #video
257
+ param :caption, :required => false
258
+ param :sourceUrl, :required => false
259
+
260
+ def request_url params={}
261
+ blog_cname = params[:blogCName]
262
+ blog_uuid = params[:blogUuid]
263
+ raise ParamIsRequiredError.new("blogCName or blogUuid is required for interface #{self.class.name}") unless blog_cname || blog_uuid
264
+ API.url_for "/blog/#{blog_cname || blog_uuid}/post"
265
+ end
266
+ end
267
+
268
+ class EditPost < Base
269
+ verb :post
270
+ param :id, :required => true
271
+ param :tag, :required => false
272
+ param :slug, :required => false
273
+ #text
274
+ param :title, :required => false
275
+ param :body, :required => false
276
+ #photo
277
+ param :caption, :required => false
278
+ param :layout, :required => false
279
+ param :data, :required => false
280
+ param :itemDesc, :required => false
281
+ #link
282
+ param :title, :required => false
283
+ param :url, :required => false
284
+ param :description, :required => false
285
+
286
+ #audio
287
+ param :caption, :required => false
288
+ param :data, :required => false
289
+ param :musicName, :required => false
290
+ param :musicSinger, :required => false
291
+ param :albumName, :required => false
292
+
293
+ #video
294
+ param :caption, :required => false
295
+ param :sourceUrl, :required => false
296
+
297
+ def request_url params={}
298
+ blog_cname = params[:blogCName]
299
+ blog_uuid = params[:blogUuid]
300
+ raise ParamIsRequiredError.new("blogCName or blogUuid is required for interface #{self.class.name}") unless blog_cname || blog_uuid
301
+ type = params[:type]
302
+ raise ParamIsRequiredError.new("type is required for interface #{self.class.name}") unless type
303
+ API.url_for "/blog/#{blog_cname || blog_uuid}/post/edit"
304
+ end
305
+ end
306
+
307
+ class DeletePost < Base
308
+ verb :post
309
+ param :id, :required => true
310
+ def request_url params={}
311
+ blog_cname = params[:blogCName]
312
+ blog_uuid = params[:blogUuid]
313
+ raise ParamIsRequiredError.new("blogCName or blogUuid is required for interface #{self.class.name}") unless blog_cname || blog_uuid
314
+ API.url_for "/blog/#{blog_cname || blog_uuid}/post/delete"
315
+ end
316
+ end
317
+
318
+ class ReblogPost < Base
319
+ verb :post
320
+ param :id, :required => true
321
+ param :tag, :required => false
322
+ param :comment, :required => false
323
+ def request_url params={}
324
+ blog_cname = params[:blogCName]
325
+ blog_uuid = params[:blogUuid]
326
+ raise ParamIsRequiredError.new("blogCName or blogUuid is required for interface #{self.class.name}") unless blog_cname || blog_uuid
327
+ API.url_for "/blog/#{blog_cname || blog_uuid}/post/reblog"
328
+ end
329
+ end
330
+
198
331
  class HomeFeeds < Base
199
332
  param :limit, :required => false
200
333
  param :offset, :required => false
@@ -218,7 +351,7 @@ module DiandianOAuth
218
351
 
219
352
  def request_url params={}
220
353
  tag = params[:tag]
221
- raise ParamIsRequiredException("tag is required for interface #{self.class.name}") unless tag
354
+ raise ParamIsRequiredError.new("tag is required for interface #{self.class.name}") unless tag
222
355
  API.url_for "/tag/posts/#{tag}"
223
356
  end
224
357
  end #TagFeeds
@@ -239,11 +372,81 @@ module DiandianOAuth
239
372
  end
240
373
  end # Unfollow
241
374
 
375
+ class WatchTag < Base
376
+ verb :post
377
+ def request_url params={}
378
+ tag = params[:tag]
379
+ raise ParamIsRequiredError.new("tag is required for interface #{self.class.name}") unless tag
380
+ API.url_for '/tag/watch/#{tag}'
381
+ end
382
+ end
383
+
384
+ class UnwatchTag < Base
385
+ verb :post
386
+ def request_url params={}
387
+ tag = params[:tag]
388
+ raise ParamIsRequiredError.new("tag is required for interface #{self.class.name}") unless tag
389
+ API.url_for '/tag/watch/#{tag}'
390
+ end
391
+ end
392
+
242
393
  class Submissions < Base
243
394
  def request_url params={}
244
395
  blog_cname = params[:blogCName]
245
- raise ParamIsRequiredException("blogCName is required for interface #{self.class.name}") unless blog_cname
246
- API.url_for "/blog/#{blog_cname}/submission"
396
+ blog_uuid = params[:blogUuid]
397
+ raise ParamIsRequiredError.new("blogCName or blogUuid is required for interface #{self.class.name}") unless blog_cname || blog_uuid
398
+ API.url_for "/blog/#{blog_cname||blog_uuid}/submission"
399
+ end
400
+ end #Submissions
401
+
402
+ class Submit < Base
403
+ verb :post
404
+ param :tag, :required => false
405
+ param :slug, :required => false
406
+ #text
407
+ param :title, :required => false
408
+ param :body, :required => false
409
+ #photo
410
+ param :caption, :required => false
411
+ param :layout, :required => false
412
+ param :data, :required => false
413
+ param :itemDesc, :required => false
414
+ #link
415
+ param :title, :required => false
416
+ param :url, :required => false
417
+ param :description, :required => false
418
+
419
+ #audio
420
+ param :caption, :required => false
421
+ param :data, :required => false
422
+ param :musicName, :required => false
423
+ param :musicSinger, :required => false
424
+ param :albumName, :required => false
425
+
426
+ #video
427
+ param :caption, :required => false
428
+ param :sourceUrl, :required => false
429
+
430
+ def request_url params={}
431
+ blog_cname = params[:blogCName]
432
+ blog_uuid = params[:blogUuid]
433
+ raise ParamIsRequiredError.new("blogCName or blogUuid is required for interface #{self.class.name}") unless blog_cname || blog_uuid
434
+ type = params[:type]
435
+ raise ParamIsRequiredError.new("type is required for interface #{self.class.name}") unless type
436
+ API.url_for "/blog/#{blog_cname || blog_uuid}/submission/#{type}"
437
+ end
438
+ end
439
+
440
+ class RejectSubmission < Base
441
+ verb :post
442
+ param :reason, :required => false
443
+ def request_url params={}
444
+ blog_cname = params[:blogCName]
445
+ blog_uuid = params[:blogUuid]
446
+ raise ParamIsRequiredError.new("blogCName or blogUuid is required for interface #{self.class.name}") unless blog_cname || blog_uuid
447
+ id = params[:id]
448
+ raise ParamIsRequiredError.new("id is required for interface #{self.class.name}") unless id
449
+ API.url_for "/blog/#{blog_cname || blog_uuid}/submission/reject/#{id}"
247
450
  end
248
451
  end
249
452
  end # Interface
@@ -1,7 +1,9 @@
1
1
  require 'oauth2'
2
+ require 'diandian_oauth/client/callbacks'
2
3
  module DiandianOAuth
3
4
  class Client
4
- attr_accessor :api
5
+ include DiandianOAuth::Client::Callbacks
6
+ attr_accessor :api, :client
5
7
  def initialize client_id, client_secret, options={}
6
8
  @api = options[:api] || DiandianOAuth::API.new
7
9
  @redirect_uri = options[:redirect_uri]
@@ -9,7 +11,16 @@ module DiandianOAuth
9
11
  :authorize_url => @api.authorize_url,
10
12
  :token_url => @api.token_url
11
13
  }
12
- end
14
+ self.config_client_middleware(@client)
15
+ end
16
+
17
+ def config_client_middleware client
18
+ client.options[:connection_build] = Proc.new do |builder|
19
+ builder.request :multipart
20
+ builder.request :url_encoded
21
+ builder.adapter :net_http
22
+ end
23
+ end
13
24
 
14
25
  def authorize_url response_type='code', scope=[]
15
26
  if response_type.is_a? Array
@@ -38,13 +49,14 @@ module DiandianOAuth
38
49
  else
39
50
  begin
40
51
  DiandianOAuth.logger.warn('redirect_url is required for authorization_code grant type') unless @redirect_uri
41
- @access_token = @client.get_token(
42
- :client_id => @client.id,
43
- :client_secret => @client.secret,
44
- :grant_type => 'authorization_code',
45
- :code => code_or_hash,
46
- :redirect_uri => @redirect_uri
47
- )
52
+ @access_token = @client.auth_code.get_token(code_or_hash, {:redirect_uri => @redirect_uri})
53
+ #@access_token = @client.get_token(
54
+ # :client_id => @client.id,
55
+ # :client_secret => @client.secret,
56
+ # :grant_type => 'authorization_code',
57
+ # :code => code_or_hash,
58
+ # :redirect_uri => @redirect_uri
59
+ #)
48
60
  rescue OAuth2::Error => e
49
61
  DiandianOAuth.logger.error e.to_s
50
62
  raise e
@@ -60,8 +72,24 @@ module DiandianOAuth
60
72
  if interface
61
73
  access_token = self.access_token
62
74
  raise 'access_token is required' unless access_token
63
- if force
64
- interface.apply! access_token, args[0], &block
75
+ response = if force
76
+ begin
77
+ token_expired = false
78
+ response = interface.apply access_token, args[0], &block
79
+ response.validate!
80
+ rescue TokenExpiredError => e
81
+ if DiandianOAuth.logger.debug?
82
+ DiandianOAuth.logger.debug("token '#{access_token.inspect}' expired")
83
+ end
84
+ new_access_token = access_token.refresh!
85
+ self.token_refreshed new_access_token
86
+ if DiandianOAuth.logger.debug?
87
+ DiandianOAuth.logger.debug("refreshed '#{access_token.inspect}' with '#{new_access_token}'")
88
+ end
89
+ self.access_token = access_token = new_access_token
90
+ token_expired = true
91
+ end while token_expired
92
+ response
65
93
  else
66
94
  interface.apply access_token, args[0], &block
67
95
  end # force
@@ -0,0 +1,49 @@
1
+ module DiandianOAuth
2
+ class Client
3
+ module Callbacks
4
+ class Callback
5
+ attr_accessor :executor
6
+ def initialize proc_or_method
7
+ self.executor = proc_or_method
8
+ end
9
+ def apply client, *args, &block
10
+ case executor
11
+ when Symbol then client.send(executor, *args, &block)
12
+ when Proc then executor.call( client, *args, &block)
13
+ end
14
+ end
15
+ end
16
+ def self.included base
17
+ base.extend ClassMethods
18
+ base.send :include, InstanceMethods
19
+ base.class_eval do
20
+ self.callbacks = {}
21
+ end
22
+ end
23
+
24
+ module ClassMethods
25
+ def callbacks name=nil
26
+ if name
27
+ @callbacks[name] ||= []
28
+ else
29
+ @callbacks
30
+ end
31
+ end
32
+ def callbacks= callbacks
33
+ @callbacks = callbacks
34
+ end
35
+ def token_refreshed proc_or_method
36
+ self.callbacks(:token_refreshed) << Callback.new( proc_or_method)
37
+ end
38
+ private
39
+ end
40
+ module InstanceMethods
41
+ def token_refreshed access_token
42
+ self.class.callbacks[:token_refreshed].each do |callback|
43
+ callback.apply(self, access_token)
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -1,19 +1,236 @@
1
1
  module DiandianOAuth
2
2
 
3
- class OAuthException < ::Exception
3
+ class Error < ::StandardError
4
4
  end
5
5
 
6
- class TokenExpiredException < OAuthException
6
+ class TokenExpiredError < Error
7
7
  end
8
8
 
9
- class RefreshTokenExpireException < OAuthException
9
+ class RefreshTokenExpireError < Error
10
10
  end
11
11
  # APIException
12
- class APIException < OAuthException
12
+ class APIError < Error
13
13
  end
14
- class ParamIsRequiredException < APIException
14
+
15
+ class ResponseError < APIError
16
+ end
17
+
18
+ class InvalidateRequestError < ResponseError
19
+
20
+ end
21
+
22
+ class UnauthorizedClientError < ResponseError
23
+
24
+ end
25
+
26
+ class AccessDeniedError < ResponseError
27
+
28
+ end
29
+
30
+ class UnsupportedResponseTypeError < ResponseError
31
+
32
+ end
33
+
34
+ class InvalidScopeError < ResponseError
35
+
36
+ end
37
+
38
+ class TemporarilyUnavailableError < ResponseError
39
+
40
+ end
41
+
42
+ class ParamIsRequiredError < APIError
43
+ end
44
+ class IllegalParamError < APIError
45
+ end
46
+ ## 400000
47
+ class ClientError < APIError
48
+ end
49
+
50
+ ## 400001
51
+ class ParameterError < APIError
52
+
53
+ end
54
+
55
+ ## 400010
56
+ class EmailError < APIError
57
+ end
58
+
59
+ ## 400011
60
+ class PasswordError < APIError
61
+ end
62
+
63
+ ## 400012
64
+ class EccentricAccountError < APIError
65
+
66
+ end
67
+
68
+ ## 400013
69
+ class EmailFormatError < APIError
70
+
71
+ end
72
+
73
+ ## 400014
74
+ class PasswordFormatError < APIError
75
+
76
+ end
77
+
78
+ ## 400015
79
+ class EmailExistsError < APIError
80
+
81
+ end
82
+
83
+
84
+
85
+ ## 400020
86
+ class BindingFailError < APIError
87
+
88
+ end
89
+
90
+ ## 40003x
91
+ class RelationError < APIError
92
+
93
+ end
94
+
95
+ ## 400030
96
+ class FollowError < RelationError
97
+
98
+ end
99
+ ## 400031
100
+ class UnfollowError < RelationError
101
+
102
+ end
103
+
104
+ ## 400040
105
+ class IllegalContentError < APIError
106
+
107
+ end
108
+
109
+ ## 40005x
110
+ class InboxError < APIError
111
+
112
+ end
113
+
114
+ ## 400050
115
+ class InboxContentCannotBeEmptyError < APIError
116
+
117
+ end
118
+
119
+ ## 400051
120
+ class InboxContentTooLongError < APIError
121
+
15
122
  end
16
- class IllegalParamException < APIException
123
+
124
+ ## 400052
125
+ class InboxClosedError < APIError
126
+
127
+ end
128
+
129
+ ## 400053
130
+ class CannotSendToOwnBlogError < APIError
131
+
132
+ end
133
+
134
+ ## 400060
135
+ class OperationTooFastError < APIError
136
+
137
+ end
138
+
139
+ ## 400070
140
+ class BlogClosedError < APIError
141
+
142
+ end
143
+
144
+
145
+ ## 40008x
146
+ class VerifyCodeError < APIError
147
+
148
+ end
149
+
150
+ ## 400080
151
+ class VerifyCodeExpiredError < VerifyCodeError
152
+
153
+ end
154
+
155
+
156
+ ## 400081
157
+ class VerifyCodeWrongError < VerifyCodeError
158
+
17
159
  end
160
+
161
+ ## 401xxx
162
+ class AuthorizationError < APIError
163
+ end
164
+
165
+ ## 401000
166
+ class UnauthorizedError < AuthorizationError
167
+
168
+ end
169
+
170
+ ## 403xxx
171
+ class ForbiddenError < APIError
172
+
173
+ end
174
+
175
+ ## 403000
176
+ class VisitForbiddenError < ForbiddenError
177
+
178
+ end
179
+
180
+ ## 403001
181
+ class BlogManagerRequiredError < ForbiddenError
182
+
183
+ end
184
+
185
+ ## 404xxx
186
+ class NotFoundError < APIError
187
+
188
+ end
189
+
190
+ ## 404000
191
+ class UrlNotFoundError < NotFoundError
192
+
193
+ end
194
+
195
+ ## 404002
196
+ class BlogNotFoundError < NotFoundError
197
+
198
+ end
199
+
200
+ ## 404003
201
+ class ContentNotFoundError < NotFoundError
202
+
203
+ end
204
+
205
+ ## 404004
206
+ class UserNotFoundError < NotFoundError
207
+
208
+ end
209
+
210
+ ## 500xxx
211
+ class ServerError < APIError
212
+
213
+ end
214
+
215
+ ## 500000
216
+ class InternalServerError < APIError
217
+
218
+ end
219
+
220
+ ## 500001
221
+ class PostTypeError < APIError
222
+
223
+ end
224
+
225
+ ## 500002
226
+ class InboxError < APIError
227
+
228
+ end
229
+
230
+ ## 503001
231
+ class UpgradingError < APIError
232
+
233
+ end
234
+
18
235
  # End APIException
19
236
  end
@@ -0,0 +1,77 @@
1
+ module DiandianOAuth
2
+ class Response
3
+ attr_accessor :error, :meta, :response, :internal
4
+ def self.from_response response
5
+ response_json = response.parsed
6
+ result = Response.new
7
+ result.internal = response
8
+ result.error = response_json['error']
9
+ return result if result.error
10
+ result.meta = response_json['meta']
11
+ result.response = response_json['response']
12
+ result
13
+ end
14
+
15
+ def validate
16
+ !error && meta['status'] == 200
17
+ end
18
+ alias_method :success?, :validate
19
+
20
+ # throw exception when an error occurs
21
+ def validate!
22
+ puts "error: '#{self.inspect}'"
23
+ unless self.validate
24
+ if error
25
+ exception =
26
+ case error[:error]
27
+ when 'invalid_request' then DiandianOAuth::InvalidateRequestError
28
+ when 'unauthorized_client' then DiandianOAuth::UnauthorizedClientError
29
+ when 'access_denied' then DiandianOAuth::AccessDeniedError
30
+ when 'unsupported_response_type' then DiandianOAuth::UnsupportedResponseTypeError
31
+ when 'invalid_scope' then DiandianOAuth::InvalidScopeError
32
+ when 'server_error' then DiandianOAuth::ServerError
33
+ else APIError
34
+ end
35
+ raise exception
36
+ else
37
+ exception =
38
+ case meta[:status]
39
+ when 400000 then DiandianOAuth::ClientError
40
+ when 400001 then DiandianOAuth::ParameterError
41
+ when 400010 then DiandianOAuth::EmailError
42
+ when 400011 then DiandianOAuth::PasswordError
43
+ when 400012 then DiandianOAuth::EccentricAccountError
44
+ when 400013 then DiandianOAuth::EmailFormatError
45
+ when 400014 then DiandianOAuth::PasswordFormatError
46
+ when 400015 then DiandianOAuth::EmailExistsError
47
+ when 400020 then DiandianOAuth::BindingFailError
48
+ when 400030 then DiandianOAuth::FollowError
49
+ when 400031 then DiandianOAuth::UnfollowError
50
+ when 400040 then DiandianOAuth::IllegalContentError
51
+ when 400050 then DiandianOAuth::InboxContentCannotBeEmptyError
52
+ when 400051 then DiandianOAuth::InboxContentTooLongError
53
+ when 400052 then DiandianOAuth::InboxClosedError
54
+ when 400053 then DiandianOAuth::CannotSendToOwnBlogError
55
+ when 400060 then DiandianOAuth::OperationTooFastError
56
+ when 400070 then DiandianOAuth::BlogClosedError
57
+ when 400080 then DiandianOAuth::VerifyCodeExpiredError
58
+ when 400081 then DiandianOAuth::VerifyCodeWrongError
59
+ when 401000 then DiandianOAuth::UnauthorizedError
60
+ when 403000 then DiandianOAuth::VisitForbiddenError
61
+ when 403001 then DiandianOAuth::BlogManagerRequiredError
62
+ when 404002 then DiandianOAuth::BlogNotFoundError
63
+ when 404003 then DiandianOAuth::ContentNotFoundError
64
+ when 404004 then DiandianOAuth::UserNotFoundError
65
+ when 500000 then DiandianOAuth::InternalServerError
66
+ when 500001 then DiandianOAuth::PostTypeError
67
+ when 500002 then DiandianOAuth::InboxError
68
+ when 503001 then DiandianOAuth::UpgradingError
69
+ else DiandianOAuth::APIError
70
+ end
71
+ raise exception
72
+ end
73
+ end
74
+ end
75
+
76
+ end
77
+ end
@@ -0,0 +1,61 @@
1
+ module DiandianOAuth
2
+ class ResponseMeta
3
+ attr_accessor :status, :message
4
+ def self.from_response response_json
5
+ meta = response_json['meta']
6
+ response_meta = ResponseMeta.new
7
+ response_meta.status = meta['status']
8
+ response_meta.message = meta['msg']
9
+ response_meta
10
+ end
11
+
12
+ def success?
13
+ self.validate
14
+ end
15
+
16
+ def validate
17
+ self.status == 200
18
+ end
19
+
20
+ def validate!
21
+ if !self.validate
22
+ exception =
23
+ case self.status
24
+ when 400000 then DiandianOAuth::ClientError
25
+ when 400001 then DiandianOAuth::ParameterError
26
+ when 400010 then DiandianOAuth::EmailError
27
+ when 400011 then DiandianOAuth::PasswordError
28
+ when 400012 then DiandianOAuth::EccentricAccountError
29
+ when 400013 then DiandianOAuth::EmailFormatError
30
+ when 400014 then DiandianOAuth::PasswordFormatError
31
+ when 400015 then DiandianOAuth::EmailExistsError
32
+ when 400020 then DiandianOAuth::BindingFailError
33
+ when 400030 then DiandianOAuth::FollowError
34
+ when 400031 then DiandianOAuth::UnfollowError
35
+ when 400040 then DiandianOAuth::IllegalContentError
36
+ when 400050 then DiandianOAuth::InboxContentCannotBeEmptyError
37
+ when 400051 then DiandianOAuth::InboxContentTooLongError
38
+ when 400052 then DiandianOAuth::InboxClosedError
39
+ when 400053 then DiandianOAuth::CannotSendToOwnBlogError
40
+ when 400060 then DiandianOAuth::OperationTooFastError
41
+ when 400070 then DiandianOAuth::BlogClosedError
42
+ when 400080 then DiandianOAuth::VerifyCodeExpiredError
43
+ when 400081 then DiandianOAuth::VerifyCodeWrongError
44
+ when 401000 then DiandianOAuth::UnauthorizedError
45
+ when 403000 then DiandianOAuth::VisitForbiddenError
46
+ when 403001 then DiandianOAuth::BlogManagerRequiredError
47
+ when 404002 then DiandianOAuth::BlogNotFoundError
48
+ when 404003 then DiandianOAuth::ContentNotFoundError
49
+ when 404004 then DiandianOAuth::UserNotFoundError
50
+ when 500000 then DiandianOAuth::InternalServerError
51
+ when 500001 then DiandianOAuth::PostTypeError
52
+ when 500002 then DiandianOAuth::InboxError
53
+ when 503001 then DiandianOAuth::UpgradingError
54
+ else DiandianOAuth::APIError
55
+ end
56
+ raise exception, self.message
57
+ end
58
+ self
59
+ end
60
+ end
61
+ end
@@ -1,8 +1,8 @@
1
1
  require File.join( File.dirname(__FILE__), 'test_helper')
2
2
 
3
3
  class AuthorizeTest < ActiveSupport::TestCase
4
- CLIENT_ID="3zgJwues92"
5
- CLIENT_SECRET="1rxLZr5R4sweGUATGig25VBc1ka1xDEpkIqJ"
4
+ CLIENT_ID="fr2ejCbPrO"
5
+ CLIENT_SECRET="C5Cgprqe3DC674vdnaQlujko9ItuSAOB24qa"
6
6
 
7
7
  test 'authorize_url' do
8
8
  assert_nothing_raised do
@@ -12,11 +12,12 @@ class AuthorizeTest < ActiveSupport::TestCase
12
12
  end
13
13
 
14
14
  test 'access_token' do
15
- code = '7KhUBh'
15
+ code = 'dJGgxE'
16
16
  unless code.empty?
17
17
  assert_nothing_raised do
18
- client = DiandianOAuth::Client.new CLIENT_ID, CLIENT_SECRET, :redirect_uri => 'http://example.com/callback'
18
+ client = DiandianOAuth::Client.new CLIENT_ID, CLIENT_SECRET, :redirect_uri => 'http://example.com/users/auth/diandian/callback'
19
19
  access_token = client.access_token code
20
+ p access_token
20
21
  end
21
22
  end
22
23
  end
@@ -1,14 +1,16 @@
1
1
  require File.join( File.dirname(__FILE__), 'test_helper')
2
2
 
3
+ require 'faraday/request/diandian_multipart'
4
+
3
5
  class InterfaceTest < ActiveSupport::TestCase
4
- CLIENT_ID="3zgJwues92"
5
- CLIENT_SECRET="1rxLZr5R4sweGUATGig25VBc1ka1xDEpkIqJ"
6
+ CLIENT_ID="fr2ejCbPrO"
7
+ CLIENT_SECRET="C5Cgprqe3DC674vdnaQlujko9ItuSAOB24qa"
6
8
  ACCESS_TOKEN = {
7
- :access_token => 'adbab585-ea39-47e0-87ce-da7700fd3d9b',
8
- :refresh_token => "79852349-5f2e-4e3b-93b8-845e239e61ff",
9
+ :access_token => '92eb54ba-4be0-4a75-ae2a-d185d0a0f751',
10
+ :refresh_token => "fa522c29-fc69-4d45-ab59-b9e26b9e5ed5",
9
11
  :token_type => "bearer",
10
- :expires_in => 604799,
11
- :expires_at => 1344317317,
12
+ :expires_in => 3406,
13
+ :expires_at => 1344410022,
12
14
  :scope => "write read",
13
15
  :uid => "11449"
14
16
  }
@@ -22,10 +24,46 @@ class InterfaceTest < ActiveSupport::TestCase
22
24
  test 'user_info' do
23
25
  client = self.client
24
26
  client.access_token= ACCESS_TOKEN
25
- begin
26
- p client.user_info
27
- rescue DiandianOAuth::API::TokenExpiredException => e
28
- end
27
+ p client.user_info
28
+ end
29
+
30
+ test 'user_info!' do
31
+ client = self.client
32
+ client.access_token = ACCESS_TOKEN.merge(:expires_at => Time.now.to_i - 1.day.to_i)
33
+ puts "expired?: '#{client.access_token.expired?}'"
34
+ p client.user_info!
35
+ end
36
+
37
+ test 'create_post' do
38
+ client = self.client
39
+ client.access_token = ACCESS_TOKEN
40
+ p client.create_post :blogCName => 'secretworry.diandian.com',
41
+ :type => 'text',
42
+ :state => 'published',
43
+ :title => 'Hello from diandian ruby client'
44
+ end
45
+
46
+ test 'create_photo_post' do
47
+ client = self.client
48
+ client.access_token = ACCESS_TOKEN
49
+ Faraday::Request.register_middleware :diandian_multipart => Faraday::Request::DiandianMultipart
50
+ p client.user_info!
51
+ p client.create_post! :blogCName => 'tree-hollow.diandian.com',
52
+ :type => 'photo',
53
+ :state => 'published',
54
+ :data => [Faraday::UploadIO.new('/Users/siyudu/Pictures/test/blue_700_342.jpg', 'image/jpeg'), Faraday::UploadIO.new('/Users/siyudu/Pictures/test/white_700_342.jpg', 'image/jpeg')]
55
+ end
56
+
57
+ test 'submissions' do
58
+ client = self.client
59
+ client.access_token = ACCESS_TOKEN
60
+ p client.submissions :blogCName => 'secretworry.diandian.com'
61
+ end
62
+
63
+ test 'delete_post' do
64
+ client = self.client
65
+ client.access_token = ACCESS_TOKEN
66
+ p client.delete_post :blogCName => 'secretworry.diandian.com', :id => '3fdc4740-dcce-11e1-a2d7-782bcb43b268'
29
67
  end
30
68
 
31
69
  test 'posts' do
@@ -35,6 +73,9 @@ class InterfaceTest < ActiveSupport::TestCase
35
73
  end
36
74
 
37
75
  def client
76
+ DiandianOAuth::Client.token_refreshed (lambda{|client, token|
77
+ p "token_refreshed: '#{token}'"
78
+ })
38
79
  @client ||= DiandianOAuth::Client.new CLIENT_ID, CLIENT_SECRET, :redirect_uri => 'http://example.com/callback'
39
80
  end
40
81
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: diandian-oauth
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.3
5
+ version: 0.1.1
6
6
  platform: ruby
7
7
  authors:
8
8
  - Rainer Du
@@ -69,7 +69,10 @@ files:
69
69
  - lib/diandian_oauth/api.rb
70
70
  - lib/diandian_oauth/api/interface.rb
71
71
  - lib/diandian_oauth/client.rb
72
+ - lib/diandian_oauth/client/callbacks.rb
72
73
  - lib/diandian_oauth/exceptions.rb
74
+ - lib/diandian_oauth/models/response.rb
75
+ - lib/diandian_oauth/models/response_meta.rb
73
76
  - test/diandian_oauth/api_test.rb
74
77
  - test/diandian_oauth/authorize_test.rb
75
78
  - test/diandian_oauth/interface_test.rb