douban-ruby 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data.tar.gz.sig CHANGED
Binary file
@@ -1,3 +1,16 @@
1
+ === 0.0.6 / 2010-07-10
2
+ * Douban::Authorize
3
+ * add verify_token and delete_token
4
+ * support get_book(:isbn => isbn)
5
+ * support get_movie(:imdb => imdb)
6
+ * add get_miniblog_comments
7
+ * add create_miniblog_comment
8
+ * add delete_miniblog_comment
9
+ * Douban::Book
10
+ * add method: isbn, isbn10, isbn13
11
+ * Douban::Movie
12
+ * add method: imdb
13
+
1
14
  === 0.0.5 / 2010-07-04
2
15
  * Douban::Authorize
3
16
  * all modify_* functions will return an Object if success, otherwise nil. In
@@ -11,7 +11,10 @@ lib/douban/equal.rb
11
11
  lib/douban/event.rb
12
12
  lib/douban/mail.rb
13
13
  lib/douban/miniblog.rb
14
+ lib/douban/miniblog_comment.rb
15
+ lib/douban/miniblog_comments.rb
14
16
  lib/douban/note.rb
17
+ lib/douban/page_info.rb
15
18
  lib/douban/people.rb
16
19
  lib/douban/recommendation.rb
17
20
  lib/douban/recommendation_comment.rb
@@ -23,12 +26,16 @@ spec/douban/authorize_spec.rb
23
26
  spec/douban/collection_spec.rb
24
27
  spec/douban/event_spec.rb
25
28
  spec/douban/mail_spec.rb
29
+ spec/douban/miniblog_comment_spec.rb
30
+ spec/douban/miniblog_comments_spec.rb
26
31
  spec/douban/miniblog_spec.rb
27
32
  spec/douban/note_spec.rb
33
+ spec/douban/page_info_spec.rb
28
34
  spec/douban/people_spec.rb
29
35
  spec/douban/recommendation_comment_spec.rb
30
36
  spec/douban/recommendation_spec.rb
31
37
  spec/douban/review_spec.rb
38
+ spec/douban/subject_spec.rb
32
39
  spec/douban/tag_spec.rb
33
40
  spec/douban_spec.rb
34
41
  spec/spec_helper.rb
data/Rakefile CHANGED
@@ -4,10 +4,12 @@ $:.unshift(File.dirname(__FILE__) + "/lib")
4
4
  require 'douban'
5
5
 
6
6
  ENV["SPEC_OPTS"] ||= "-f nested --color -b"
7
+ ENV["RDOC_OPTS"] ||= "-c UTF-8"
7
8
 
8
9
  Hoe.spec 'douban-ruby' do
9
- developer "Hoooopo", "hoooopo@gmail.com"
10
10
  developer "LI Daobing", "lidaobing@gmail.com"
11
+ developer "Hoooopo", "hoooopo@gmail.com"
12
+ extra_deps << ['oauth']
11
13
  end
12
14
 
13
15
  Hoe.plugin :minitest
@@ -32,3 +34,7 @@ namespace :spec do
32
34
  t.rcov_opts = ['--exclude' , 'gems,spec' ]
33
35
  end
34
36
  end
37
+
38
+ Rake::RDocTask.new do |rd|
39
+ rd.options << "--charset" << "UTF-8"
40
+ end
@@ -1,3 +1,4 @@
1
+ require 'pp'
1
2
  require 'rubygems'
2
3
  require 'douban'
3
4
 
@@ -17,5 +18,6 @@ print "after login, press Enter to continue\n"
17
18
 
18
19
  gets
19
20
 
20
- douban.auth
21
- print douban.get_people
21
+ pp douban.auth
22
+ pp douban.access_token
23
+ pp douban.get_people
@@ -52,6 +52,6 @@
52
52
  require 'douban/authorize'
53
53
 
54
54
  module Douban
55
- VERSION = "0.0.5"
55
+ VERSION = "0.0.6"
56
56
  end
57
57
 
@@ -10,6 +10,7 @@ require 'douban/collection'
10
10
  require 'douban/event'
11
11
  require 'douban/mail'
12
12
  require 'douban/miniblog'
13
+ require 'douban/miniblog_comments'
13
14
  require 'douban/note'
14
15
  require 'douban/people'
15
16
  require 'douban/recommendation'
@@ -94,7 +95,7 @@ module Douban
94
95
  atom=resp.body
95
96
  People.new(atom)
96
97
  else
97
- nil
98
+ debug(resp)
98
99
  end
99
100
  end
100
101
 
@@ -109,7 +110,7 @@ module Douban
109
110
  end
110
111
  friends
111
112
  else
112
- nil
113
+ debug(resp)
113
114
  end
114
115
  end
115
116
 
@@ -143,12 +144,30 @@ module Douban
143
144
  nil
144
145
  end
145
146
  end
146
- def get_book(id="")
147
- if id.to_s.size >=10
148
- resp=get("/book/subject/isbn/#{u(id.to_s)}")
147
+
148
+ # 获取书籍信息
149
+ # http://goo.gl/HaG5
150
+ #
151
+ # get_book(:isbn => isbn) => Book
152
+ # get_book(:id => id) => Book
153
+ # get_book(id) => Book
154
+ # get_book(Book) => Book (refresh Book)
155
+ def get_book(id)
156
+ resp = case id
157
+ when Book
158
+ get("/book/subject/#{u id.subject_id}")
159
+ when Hash
160
+ if id[:isbn]
161
+ get("/book/subject/isbn/#{u id[:isbn]}")
162
+ elsif id[:id]
163
+ get("/book/subject/#{u id[:id]}")
164
+ else
165
+ raise "Hash only support :isbn or :id"
166
+ end
149
167
  else
150
- resp=get("/book/subject/#{u(id.to_s)}")
168
+ get("/book/subject/#{u id}")
151
169
  end
170
+
152
171
  if resp.code=="200"
153
172
  atom=resp.body
154
173
  Book.new(atom)
@@ -156,12 +175,30 @@ module Douban
156
175
  nil
157
176
  end
158
177
  end
159
- def get_movie(id="")
160
- if id.to_s=~/^tt\d+/
161
- resp=get("/movie/subject/imdb/#{u(id.to_s)}")
178
+
179
+ # 获取电影信息
180
+ # http://goo.gl/2fZ4
181
+ #
182
+ # get_movie(:imdb => imdb) => Movie
183
+ # get_movie(:id => id) => Movie
184
+ # get_movie(id) => Movie
185
+ # get_movie(Movie) => Movie (refresh Movie)
186
+ def get_movie(id)
187
+ resp = case id
188
+ when Movie
189
+ get("/movie/subject/#{u id.subject_id}")
190
+ when Hash
191
+ if id[:imdb]
192
+ get("/movie/subject/imdb/#{u id[:imdb]}")
193
+ elsif id[:id]
194
+ get("/movie/subject/#{u id[:id]}")
195
+ else
196
+ raise "Hash only support :imdb or :id"
197
+ end
162
198
  else
163
- resp=get("/movie/subject/#{u(id.to_s)}")
199
+ get("/movie/subject/#{u id}")
164
200
  end
201
+
165
202
  if resp.code=="200"
166
203
  atom=resp.body
167
204
  Movie.new(atom)
@@ -178,8 +215,25 @@ module Douban
178
215
  nil
179
216
  end
180
217
  end
181
- def search_book(tag="",option={:start_index=>1,:max_results=>10})
182
- resp=get("/book/subjects?tag=#{u(tag.to_s)}&start-index=#{option[:start_index]}&max-results=#{option[:max_results]}")
218
+
219
+ # :call-seq:
220
+ # search_book(:q => "search word") => [Book] or nil
221
+ # search_book(:tag => "tag name") => [Book] or nil
222
+ # search_book("search word") => [Book] or nil
223
+ #
224
+ # 搜索书籍
225
+ #
226
+ # http://goo.gl/rYDf
227
+ #
228
+ # * option
229
+ # * q: query string
230
+ # * tag:
231
+ # * start_index:
232
+ # * max_results:
233
+ def search_book(*args)
234
+ url = _subject_search_args_to_url(:book, *args)
235
+
236
+ resp=get(url)
183
237
  if resp.code=="200"
184
238
  atom=resp.body
185
239
  doc=REXML::Document.new(atom)
@@ -191,10 +245,12 @@ module Douban
191
245
  else
192
246
  nil
193
247
  end
194
-
195
248
  end
196
- def search_movie(tag="",option={:start_index=>1,:max_results=>10})
197
- resp=get("/movie/subjects?tag=#{u(tag.to_s)}&start-index=#{option[:start_index]}&max-results=#{option[:max_results]}")
249
+
250
+ def search_movie(*args)
251
+ url = _subject_search_args_to_url(:movie, *args)
252
+
253
+ resp=get(url)
198
254
  if resp.code=="200"
199
255
  atom=resp.body
200
256
  doc=REXML::Document.new(atom)
@@ -208,7 +264,9 @@ module Douban
208
264
  end
209
265
  end
210
266
  def search_music(tag="",option={:start_index=>1,:max_results=>10})
211
- resp=get("/music/subjects?tag=#{u(tag)}&start-index=#{option['start-index']}&max-results=#{option['max-results']}")
267
+ url = _subject_search_args_to_url(:music, *args)
268
+
269
+ resp=get(url)
212
270
  if resp.code=="200"
213
271
  atom=resp.body
214
272
  doc=REXML::Document.new(atom)
@@ -524,6 +582,72 @@ module Douban
524
582
  false
525
583
  end
526
584
  end
585
+
586
+ # :call-seq:
587
+ # get_miniblog_comments(aMiniblog) => MiniblogComments or nil
588
+ # get_miniblog_comments(obj) => MiniblogComments or nil
589
+ #
590
+ # 获取我说回复 (http://goo.gl/nTZK)
591
+ def get_miniblog_comments(miniblog)
592
+ miniblog_id = case miniblog
593
+ when Miniblog then miniblog.miniblog_id
594
+ else miniblog
595
+ end
596
+
597
+ resp = get("/miniblog/#{u miniblog_id}/comments")
598
+ if resp.code == "200"
599
+ MiniblogComments.new(resp.body)
600
+ else
601
+ debug(resp)
602
+ end
603
+ end
604
+
605
+ # :call-seq:
606
+ # create_miniblog_comment(aMiniblog, aString) => MiniblogComment or nil
607
+ # create_miniblog_comment(obj, aString) => MiniblogComment or nil
608
+ #
609
+ # 回应我说 (http://goo.gl/j43Z)
610
+ def create_miniblog_comment(miniblog, content)
611
+ miniblog_id = case miniblog
612
+ when Miniblog then miniblog.miniblog_id
613
+ else miniblog
614
+ end
615
+ entry = %Q{<?xml version='1.0' encoding='UTF-8'?>
616
+ <entry>
617
+ <content>#{h content}</content>
618
+ </entry>}
619
+
620
+ resp = post("/miniblog/#{u miniblog_id}/comments", entry)
621
+ if resp.code == "201"
622
+ MiniblogComment.new(resp.body)
623
+ else
624
+ debug(resp)
625
+ end
626
+ end
627
+
628
+ # :call-seq:
629
+ # delete_miniblog_comment(aMiniblogComment) => true or false
630
+ # delete_miniblog_comment(miniblog_id, comment_id) => true or false
631
+ # 删除我说
632
+ def delete_miniblog_comment(*args)
633
+ if args.size == 1 and args[0].kind_of?(MiniblogComment)
634
+ miniblog_id = args[0].miniblog_id
635
+ comment_id = args[0].comment_id
636
+ elsif args.size == 2
637
+ miniblog_id = args[0].to_s
638
+ comment_id = args[1].to_s
639
+ else
640
+ raise "unsupported argument error"
641
+ end
642
+
643
+ resp = delete("/miniblog/#{u miniblog_id}/comment/#{u comment_id}")
644
+ if resp.code == "200"
645
+ true
646
+ else
647
+ debug(resp, false)
648
+ end
649
+ end
650
+
527
651
  def get_note(note_id="")
528
652
  resp=get("/note/#{u(note_id.to_s)}")
529
653
  if resp.code=="200"
@@ -1102,6 +1226,31 @@ module Douban
1102
1226
  debug(resp, false)
1103
1227
  end
1104
1228
  end
1229
+
1230
+ # 验证Access Token是否可用
1231
+ # http://goo.gl/8v8d
1232
+ def verify_token
1233
+ resp = get("/access_token/#{@access_token.token}")
1234
+ if resp.code == "200"
1235
+ true
1236
+ elsif resp.code == "401"
1237
+ false
1238
+ else
1239
+ debug(resp, false)
1240
+ end
1241
+ end
1242
+
1243
+ # 注销一个Access Token
1244
+ # http://goo.gl/0JAB
1245
+ def delete_token
1246
+ resp = delete("/access_token/#{@access_token.token}")
1247
+ if resp.code == "200"
1248
+ true
1249
+ else
1250
+ debug(resp, false)
1251
+ end
1252
+ end
1253
+ alias_method :logout, :delete_token
1105
1254
 
1106
1255
  protected
1107
1256
  def new_request_consumer
@@ -1133,10 +1282,12 @@ module Douban
1133
1282
  def get(path,headers={})
1134
1283
  @access_token.get(path,headers)
1135
1284
  end
1136
- def post(path,data="",headers={})
1285
+ def post(path,data="",headers=nil)
1286
+ headers ||= {"Content-Type" => "application/atom+xml"}
1137
1287
  @access_token.post(path,data,headers)
1138
1288
  end
1139
- def put(path,body="",headers={})
1289
+ def put(path,body="",headers=nil)
1290
+ headers ||= {"Content-Type" => "application/atom+xml"}
1140
1291
  @access_token.put(path,body,headers)
1141
1292
  end
1142
1293
  def delete(path,headers={})
@@ -1145,6 +1296,35 @@ module Douban
1145
1296
  def head(path,headers={})
1146
1297
  @access_token.head(path,headers)
1147
1298
  end
1299
+
1300
+ def _subject_search_args_to_url(type, *args)
1301
+ arg = args.shift
1302
+
1303
+ option = case arg
1304
+ when String
1305
+ arg2 = args.shift
1306
+ arg2 ||= {}
1307
+ arg2.merge(:q => arg)
1308
+ when Hash
1309
+ arg
1310
+ else
1311
+ raise "unknown type for first arg: #{arg.class}"
1312
+ end
1313
+
1314
+ raise "extra argument" unless args.empty?
1315
+
1316
+ if option[:q].nil? and option[:tag].nil?
1317
+ raise "you must specify :q or :tag"
1318
+ end
1319
+
1320
+ url = "/#{type}/subjects?"
1321
+ url << "q=#{u option[:q]}&" if option[:q]
1322
+ url << "tag=#{u option[:tag]}&" if option[:tag]
1323
+ url << "start_index=#{u option[:start_index]}&" if option[:start_index]
1324
+ url << "max_results=#{u option[:max_results]}&" if option[:max_results]
1325
+ url.slice!(-1)
1326
+ url
1327
+ end
1148
1328
  end
1149
1329
  end
1150
1330
 
@@ -4,20 +4,20 @@ require 'douban/author'
4
4
  require 'douban/equal'
5
5
 
6
6
  module Douban
7
- class Miniblog
8
- include Douban::Equal
9
- class << self
10
- def attr_names
11
- [
12
- :id,
13
- :title,
14
- :category,
15
- :published,
16
- :link,
17
- :content,
18
- :attribute,
19
- :author
20
- ]
7
+ class Miniblog
8
+ include Douban::Equal
9
+ class << self
10
+ def attr_names
11
+ [
12
+ :id,
13
+ :title,
14
+ :category,
15
+ :published,
16
+ :link,
17
+ :content,
18
+ :attribute,
19
+ :author
20
+ ]
21
21
  end
22
22
  end
23
23
  attr_names.each do |attr|
@@ -54,6 +54,10 @@ module Douban
54
54
  author=REXML::XPath.first(doc,"./author")
55
55
  @author=Author.new(author.to_s) if author
56
56
  end
57
- end
57
+
58
+ def miniblog_id
59
+ /\/(\d+)$/.match(@id)[1].to_i rescue nil
60
+ end
61
+ end
58
62
  end
59
63
 
@@ -0,0 +1,42 @@
1
+ require'rexml/document'
2
+
3
+ require 'douban/author'
4
+ require 'douban/equal'
5
+
6
+ module Douban
7
+ class MiniblogComment
8
+ include Douban::Equal
9
+ class << self
10
+ def attr_names
11
+ [
12
+ :id,
13
+ :author,
14
+ :published,
15
+ :content
16
+ ]
17
+ end
18
+ end
19
+ attr_names.each do |attr|
20
+ attr_accessor attr
21
+ end
22
+ def initialize(atom)
23
+ doc = case atom
24
+ when REXML::Document then atom.root
25
+ when REXML::Element then atom
26
+ else REXML::Document.new(atom).root
27
+ end
28
+ @id = REXML::XPath.first(doc, "./id/text()").to_s rescue nil
29
+ author = REXML::XPath.first(doc, "./author")
30
+ @author = Author.new(author) if author
31
+ @published = REXML::XPath.first(doc, "./published/text()").to_s rescue nil
32
+ @content = REXML::XPath.first(doc, "./content/text()").to_s rescue nil
33
+ end
34
+
35
+ def miniblog_id
36
+ /miniblog\/(\d+)\/comment/.match(@id)[1].to_i rescue nil
37
+ end
38
+ def comment_id
39
+ /\/(\d+)$/.match(@id)[1].to_i rescue nil
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,31 @@
1
+ require'rexml/document'
2
+
3
+ require 'douban/author'
4
+ require 'douban/miniblog_comment'
5
+ require 'douban/page_info'
6
+
7
+ module Douban
8
+ class MiniblogComments < Struct.new(:title, :author, :comments, :page_info)
9
+ def initialize(*args)
10
+ if args.size != 1
11
+ super(*args)
12
+ return
13
+ end
14
+
15
+ atom = args[0]
16
+ doc = case atom
17
+ when REXML::Document then atom.root
18
+ when REXML::Element then atom
19
+ else REXML::Document.new(atom).root
20
+ end
21
+ self.title = REXML::XPath.first(doc, "./title/text()").to_s rescue nil
22
+ author = REXML::XPath.first(doc, "./author")
23
+ self.author = Author.new(author) if author
24
+ self.comments = []
25
+ REXML::XPath.each(doc, "./entry") do |entry|
26
+ self.comments << MiniblogComment.new(entry)
27
+ end
28
+ self.page_info = PageInfo.new(doc)
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,23 @@
1
+ require 'rexml/document'
2
+
3
+ module Douban
4
+ class PageInfo < Struct.new(:items_per_page, :start_index, :total_results)
5
+ def initialize(*args)
6
+ if args.size != 1
7
+ super(*args)
8
+ return
9
+ end
10
+
11
+ atom = args[0]
12
+ doc = case atom
13
+ when REXML::Document then atom.root
14
+ when REXML::Element then atom
15
+ else REXML::Document.new(atom).root
16
+ end
17
+
18
+ self.items_per_page = REXML::XPath.first(doc, "./openSearch:itemsPerPage/text()").to_s.to_i rescue nil
19
+ self.start_index = REXML::XPath.first(doc, "./openSearch:startIndex/text()").to_s.to_i rescue nil
20
+ self.total_results = REXML::XPath.first(doc, "./openSearch:totalResults/text()").to_s.to_i rescue nil
21
+ end
22
+ end
23
+ end
@@ -1,6 +1,8 @@
1
1
  require 'rexml/document'
2
2
  require 'douban/tag'
3
+ require 'douban/author'
3
4
  require 'douban/equal'
5
+
4
6
  module Douban
5
7
  class Subject
6
8
  include Douban::Equal
@@ -22,17 +24,23 @@ module Douban
22
24
  attr_names.each do |attr|
23
25
  attr_accessor attr
24
26
  end
25
- def initialize(atom='')
26
- doc = atom.kind_of?(REXML::Element) ? atom : REXML::Document.new(atom)
27
- id=REXML::XPath.first(doc,".//id")
27
+ def initialize(atom='')
28
+ doc = case atom
29
+ when REXML::Document then atom.root
30
+ when REXML::Element then atom
31
+ when nil then nil
32
+ else REXML::Document.new(atom).root
33
+ end
34
+
35
+ id=REXML::XPath.first(doc,"./id")
28
36
  @id=id.text if id
29
- title=REXML::XPath.first(doc,".//title")
37
+ title=REXML::XPath.first(doc,"./title")
30
38
  @title=title.text if title
31
39
  @category={}
32
- category=REXML::XPath.first(doc,".//category")
40
+ category=REXML::XPath.first(doc,"./category")
33
41
  @category['term']=category.attributes['term'] if category
34
42
  @category['scheme']=category.attributes['scheme'] if category
35
- REXML::XPath.each(doc,".//db:tag") do |tag|
43
+ REXML::XPath.each(doc,"./db:tag") do |tag|
36
44
  @tag||=[]
37
45
  t=Tag.new
38
46
  t.title=tag.attributes['name']
@@ -40,48 +48,72 @@ module Douban
40
48
  @tag<< t
41
49
  end
42
50
  @author||=Author.new
43
- name=REXML::XPath.first(doc,".//author/name")
51
+ name=REXML::XPath.first(doc,"./author/name")
44
52
  @author.name=name.text if name
45
- uri=REXML::XPath.first(doc,".//author/uri")
53
+ uri=REXML::XPath.first(doc,"./author/uri")
46
54
  @author.uri=uri.text if uri
47
- REXML::XPath.each(doc,".//author/link") do |link|
55
+ REXML::XPath.each(doc,"./author/link") do |link|
48
56
  @author.link||={}
49
57
  @author.link[link.attributes['rel']]=link.attributes['href']
50
58
  end
51
- summary=REXML::XPath.first(doc,".//summary")
59
+ summary=REXML::XPath.first(doc,"./summary")
52
60
  @summary=summary.text if summary
53
- REXML::XPath.each(doc,".//link") do |link|
61
+ REXML::XPath.each(doc,"./link") do |link|
54
62
  @link||={}
55
63
  @link[link.attributes['rel']]=link.attributes['href']
56
64
  end
57
- REXML::XPath.each(doc,".//db:attribute") do |attribute|
65
+ REXML::XPath.each(doc,"./db:attribute") do |attribute|
58
66
  @attribute||={}
59
67
  @attribute[attribute.attributes['name']]=attribute.text
60
68
  end
61
69
  @rating={}
62
- rating=REXML::XPath.first(doc,".//gd:rating")
70
+ rating=REXML::XPath.first(doc,"./gd:rating")
63
71
  if rating
64
72
  @rating['min']=rating.attributes['min']
65
73
  @rating['numRaters']=rating.attributes['numRaters']
66
74
  @rating['average']=rating.attributes['average']
67
75
  @rating['max']=rating.attributes['max']
68
76
  end
69
- end
70
- end
77
+ end #initialize
78
+
79
+ def subject_id
80
+ /\/(\d+)$/.match(@id)[1].to_i rescue nil
81
+ end
82
+
83
+ end # class Subject
84
+
71
85
  class Movie<Subject
72
86
  def initialize(atom)
73
87
  super(atom)
74
88
  end
89
+
90
+ def imdb
91
+ /(tt\d+)\/$/.match(@attribute["imdb"])[1] rescue nil
92
+ end
75
93
  end
94
+
76
95
  class Book<Subject
77
96
  def initialize(atom)
78
97
  super(atom)
79
98
  end
99
+
100
+ def isbn10
101
+ @attribute["isbn10"] rescue nil
102
+ end
103
+
104
+ def isbn13
105
+ @attribute["isbn13"] rescue nil
106
+ end
107
+
108
+ def isbn
109
+ isbn13 ? isbn13 : isbn10
110
+ end
80
111
  end
112
+
81
113
  class Music<Subject
82
114
  def initialize(atom)
83
115
  super(atom)
84
116
  end
85
117
  end
86
- end
118
+ end
87
119
 
@@ -61,8 +61,9 @@ module Douban
61
61
  context "logged in with oauth" do
62
62
  before(:each) do
63
63
  Authorize.debug = true
64
- @access_token = '0306646daca492b609132d4905edb822'
65
- @access_secret = '22070cec426cb925'
64
+ @access_token = 'be84e4bc8d0581d03b8eae35a7108570'
65
+ @access_secret = '16eeaa7b1053323c'
66
+ @uid = '43100799'
66
67
  @authorize.access_token = OAuth::Token.new(@access_token, @access_secret)
67
68
  end
68
69
 
@@ -76,7 +77,7 @@ module Douban
76
77
  it "should works" do
77
78
  people = @authorize.get_people
78
79
  people.nil?.should == false
79
- people.uid.should == "41502874"
80
+ people.uid.should == @uid
80
81
  end
81
82
  end
82
83
 
@@ -137,6 +138,22 @@ module Douban
137
138
  miniblogs[0].id.should_not == miniblogs[-1].id
138
139
  end
139
140
  end
141
+
142
+ context "get_miniblog_comments" do
143
+ it "should return [MiniblogComment] with different id" do
144
+ comments = @authorize.get_miniblog_comments(378744647)
145
+ comments.comments.size.should >= 2
146
+ comments.comments[0].id.should_not == comments.comments[-1].id
147
+ end
148
+ end
149
+
150
+ context "create_miniblog_comment" do
151
+ it "should works" do
152
+ comment = @authorize.create_miniblog_comment(374774226, "单元测试#{rand}")
153
+ comment.class.should == MiniblogComment
154
+ @authorize.delete_miniblog_comment(comment).should == true
155
+ end
156
+ end
140
157
  end
141
158
 
142
159
  context "recommendation" do
@@ -235,12 +252,12 @@ module Douban
235
252
  end
236
253
 
237
254
  context "event" do
238
- context "create_event" do
239
- it "should return Event" do
240
- event = @authorize.create_event("douban-ruby 单元测试", "event 好像不能自动删除", "大山子798艺术区 IT馆")
241
- event.class.should == Douban::Event
242
- end
243
- end
255
+ #context "create_event" do
256
+ # it "should return Event" do
257
+ # event = @authorize.create_event("douban-ruby 单元测试", "event 好像不能自动删除", "大山子798艺术区 IT馆")
258
+ # event.class.should == Douban::Event
259
+ # end
260
+ #end
244
261
 
245
262
  context "get_event_participant_people" do
246
263
  it "should return [People] with different id" do
@@ -454,15 +471,62 @@ module Douban
454
471
  book = @authorize.get_book(1088840)
455
472
  book.class.should == Book
456
473
  end
474
+
475
+ it "should support :id => id" do
476
+ @authorize.get_book(:id => 1088840).should == @authorize.get_book(1088840)
477
+ end
478
+
479
+ it "should support :isbn => isbn" do
480
+ @authorize.get_book(:isbn => 9787040048803).should == @authorize.get_book(1088840)
481
+ end
482
+
483
+ it "should support Book" do
484
+ book = @authorize.get_book(1088840)
485
+ @authorize.get_book(book).should == book
486
+ end
487
+ end
488
+
489
+ context "get_movie" do
490
+ it "should return Movie" do
491
+ movie = @authorize.get_movie(1858711)
492
+ movie.class.should == Movie
493
+ end
494
+
495
+ it "should support :id => id" do
496
+ @authorize.get_movie(:id => 1858711).should == @authorize.get_movie(1858711)
497
+ end
498
+
499
+ it "should support :imdb => imdb" do
500
+ @authorize.get_movie(:imdb => 'tt0435761').should == @authorize.get_movie(1858711)
501
+ end
502
+
503
+ it "should support Movie" do
504
+ movie = @authorize.get_movie(1858711)
505
+ @authorize.get_movie(movie).should == movie
506
+ end
457
507
  end
458
508
 
459
509
  context "search_book" do
460
- it "should return [Book] with different id" do
510
+ it "should support query" do
461
511
  books = @authorize.search_book("ruby")
462
512
  books.size.should >= 2
463
513
  books[0].class.should == Book
464
514
  books[0].id.should_not == books[-1].id
465
515
  end
516
+
517
+ it "should support :q => query" do
518
+ books = @authorize.search_book(:q => "ruby")
519
+ books.size.should >= 2
520
+ books[0].class.should == Book
521
+ books[0].id.should_not == books[-1].id
522
+ end
523
+
524
+ it "should support :tag => tag" do
525
+ books = @authorize.search_book(:tag => "ruby")
526
+ books.size.should >= 2
527
+ books[0].class.should == Book
528
+ books[0].id.should_not == books[-1].id
529
+ end
466
530
  end
467
531
  context "search_movie" do
468
532
  it "should return [Movie] with different id" do
@@ -500,8 +564,12 @@ module Douban
500
564
  end
501
565
  end
502
566
  end
503
-
504
-
567
+
568
+ context "verify_token" do
569
+ it "should return true" do
570
+ @authorize.verify_token.should == true
571
+ end
572
+ end
505
573
  end # context "logged in with oauth"
506
574
  end #describe
507
575
  end #Module
@@ -0,0 +1,42 @@
1
+ require File.join(File.dirname(__FILE__), '/../spec_helper')
2
+
3
+ require 'douban/miniblog_comment'
4
+
5
+ module Douban
6
+ describe MiniblogComment do
7
+ before do
8
+ @s = %Q{<entry>
9
+ <id>http://api.douban.com/miniblog/378744647/comment/12638415</id>
10
+ <author>
11
+ <link href="http://api.douban.com/people/3918884" rel="self"/>
12
+ <link href="http://www.douban.com/people/Ben.Dan/" rel="alternate"/>
13
+ <link href="http://t.douban.com/icon/u3918884-8.jpg" rel="icon"/>
14
+ <name>積み木</name>
15
+ <uri>http://api.douban.com/people/3918884</uri>
16
+ </author>
17
+ <published>2010-07-07T03:19:07+08:00</published>
18
+ <content>都爱远射哈哈</content>
19
+ </entry>}
20
+ end
21
+
22
+ it "should correct deserialize from string" do
23
+ comment = MiniblogComment.new(@s)
24
+ comment.id.should == "http://api.douban.com/miniblog/378744647/comment/12638415"
25
+ comment.author.class.should == Author
26
+ comment.published.should == "2010-07-07T03:19:07+08:00"
27
+ comment.content.should == "都爱远射哈哈"
28
+ comment.miniblog_id.should == 378744647
29
+ comment.comment_id.should == 12638415
30
+ end
31
+
32
+ it "should correct deserialize from REXML::Document" do
33
+ MiniblogComment.new(REXML::Document.new(@s)).should == MiniblogComment.new(@s)
34
+ end
35
+
36
+ it "should correct deserialize from REXML::Element" do
37
+ MiniblogComment.new(REXML::Document.new(@s).root).should == MiniblogComment.new(@s)
38
+ end
39
+ end
40
+ end
41
+
42
+
@@ -0,0 +1,66 @@
1
+ require File.join(File.dirname(__FILE__), '/../spec_helper')
2
+
3
+ require 'douban/miniblog_comments'
4
+
5
+ module Douban
6
+ describe MiniblogComments do
7
+ before do
8
+ @s = %Q{<?xml version="1.0" encoding="UTF-8"?>
9
+ <feed xmlns="http://www.w3.org/2005/Atom" xmlns:db="http://www.douban.com/xmlns/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:opensearch="http://a9.com/-/spec/opensearchrss/1.0/">
10
+ <title>嗷嗷嗷嗷 的回应</title>
11
+ <author>
12
+ <link href="http://api.douban.com/people/1966902" rel="self"/>
13
+ <link href="http://www.douban.com/people/1966902/" rel="alternate"/>
14
+ <link href="http://t.douban.com/icon/u1966902-13.jpg" rel="icon"/>
15
+ <name>戳戳三文鱼</name>
16
+ <uri>http://api.douban.com/people/1966902</uri>
17
+ </author>
18
+ <entry>
19
+ <id>http://api.douban.com/miniblog/378744647/comment/12638415</id>
20
+ <author>
21
+ <link href="http://api.douban.com/people/3918884" rel="self"/>
22
+ <link href="http://www.douban.com/people/Ben.Dan/" rel="alternate"/>
23
+ <link href="http://t.douban.com/icon/u3918884-8.jpg" rel="icon"/>
24
+ <name>積み木</name>
25
+ <uri>http://api.douban.com/people/3918884</uri>
26
+ </author>
27
+ <published>2010-07-07T03:19:07+08:00</published>
28
+ <content>都爱远射哈哈</content>
29
+ </entry>
30
+ <entry>
31
+ <id>http://api.douban.com/miniblog/378744647/comment/12638491</id>
32
+ <author>
33
+ <link href="http://api.douban.com/people/1966902" rel="self"/>
34
+ <link href="http://www.douban.com/people/1966902/" rel="alternate"/>
35
+ <link href="http://t.douban.com/icon/u1966902-13.jpg" rel="icon"/>
36
+ <name>戳戳三文鱼</name>
37
+ <uri>http://api.douban.com/people/1966902</uri>
38
+ </author>
39
+ <published>2010-07-07T03:20:17+08:00</published>
40
+ <content>两脚都挺漂亮的,边裁今天不给力啊,吹掉荷兰和乌拉圭的不是越位的“越位”球</content>
41
+ </entry>
42
+ <openSearch:itemsPerPage>10</openSearch:itemsPerPage>
43
+ <openSearch:startIndex>1</openSearch:startIndex>
44
+ <openSearch:totalResults>2</openSearch:totalResults>
45
+ </feed>}
46
+ end
47
+
48
+ it "should correct deserialize from string" do
49
+ comments = MiniblogComments.new(@s)
50
+ comments.title.should == "嗷嗷嗷嗷 的回应"
51
+ comments.author.class.should == Author
52
+ comments.comments.size.should == 2
53
+ comments.comments[0].class.should == MiniblogComment
54
+ comments.page_info.should == PageInfo.new(10,1,2)
55
+ end
56
+
57
+ it "should correct deserialize from REXML::Document" do
58
+ MiniblogComments.new(REXML::Document.new(@s)).should == MiniblogComments.new(@s)
59
+ end
60
+
61
+ it "should correct deserialize from REXML::Element" do
62
+ MiniblogComments.new(REXML::Document.new(@s).root).should == MiniblogComments.new(@s)
63
+ end
64
+ end
65
+ end
66
+
@@ -27,6 +27,7 @@ eos
27
27
  it "should correct deserialize from string" do
28
28
  miniblog = Douban::Miniblog.new(@s)
29
29
  miniblog.id.should == "http://api.douban.com/miniblog/374100199"
30
+ miniblog.miniblog_id.should == 374100199
30
31
  miniblog.title.should == '<b>单元测试0.921892231299059'
31
32
  miniblog.category.should == {"term"=>"http://www.douban.com/2007#miniblog.saying", "scheme"=>"http://www.douban.com/2007#kind"}
32
33
  miniblog.published.should == "2010-06-30T19:27:41+08:00"
@@ -0,0 +1,26 @@
1
+ require File.join(File.dirname(__FILE__), '/../spec_helper')
2
+
3
+ require 'douban/page_info'
4
+
5
+ module Douban
6
+ describe PageInfo do
7
+ before do
8
+ @s = %Q{<?xml version="1.0" encoding="UTF-8"?>
9
+ <feed xmlns="http://www.w3.org/2005/Atom" xmlns:db="http://www.douban.com/xmlns/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:opensearch="http://a9.com/-/spec/opensearchrss/1.0/">
10
+ <openSearch:itemsPerPage>10</openSearch:itemsPerPage>
11
+ <openSearch:startIndex>1</openSearch:startIndex>
12
+ <openSearch:totalResults>2</openSearch:totalResults>
13
+ </feed>}
14
+ end
15
+
16
+ it "should correct deserialize from string" do
17
+ PageInfo.new(@s).should == PageInfo.new(10,1,2)
18
+ end
19
+ it "should correct deserialize from REXML::Document" do
20
+ PageInfo.new(REXML::Document.new(@s)).should == PageInfo.new(10,1,2)
21
+ end
22
+ it "should correct deserialize from REXML::Element" do
23
+ PageInfo.new(REXML::Document.new(@s).root).should == PageInfo.new(10,1,2)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,136 @@
1
+ require File.join(File.dirname(__FILE__), '/../spec_helper')
2
+
3
+ require 'douban/subject'
4
+
5
+ module Douban
6
+ describe Subject do
7
+ before do
8
+ @s = %Q{<?xml version="1.0" encoding="UTF-8"?>
9
+ <entry xmlns="http://www.w3.org/2005/Atom" xmlns:db="http://www.douban.com/xmlns/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:opensearch="http://a9.com/-/spec/opensearchrss/1.0/">
10
+ <id>http://api.douban.com/book/subject/1088840</id>
11
+ <title>无机化学(下)/高等学校教材</title>
12
+ <category scheme="http://www.douban.com/2007#kind" term="http://www.douban.com/2007#book"/>
13
+ <author>
14
+ <name>武汉大学、吉林大学</name>
15
+ </author>
16
+ <link href="http://api.douban.com/book/subject/1088840" rel="self"/>
17
+ <link href="http://book.douban.com/subject/1088840/" rel="alternate"/>
18
+ <link href="http://img2.douban.com/spic/s1075910.jpg" rel="image"/>
19
+ <link href="http://api.douban.com/collection/266907549" rel="collection"/>
20
+ <db:attribute name="author">武汉大学、吉林大学</db:attribute>
21
+ <db:attribute name="isbn10">7040048809</db:attribute>
22
+ <db:attribute name="isbn13">9787040048803</db:attribute>
23
+ <db:attribute name="title">无机化学(下)/高等学校教材</db:attribute>
24
+ <db:attribute name="pages">1185</db:attribute>
25
+ <db:attribute name="price">26.5</db:attribute>
26
+ <db:attribute name="publisher">高等教育出版社</db:attribute>
27
+ <db:attribute name="binding">平装</db:attribute>
28
+ <db:attribute name="pubdate">2005-1-1</db:attribute>
29
+ <db:tag count="23" name="化学"/>
30
+ <db:tag count="16" name="无机化学"/>
31
+ <db:tag count="10" name="教材"/>
32
+ <db:tag count="6" name="武汉大学"/>
33
+ <db:tag count="3" name="Chemistry"/>
34
+ <db:tag count="2" name="科学"/>
35
+ <db:tag count="2" name="吉林大学"/>
36
+ <db:tag count="1" name="无机"/>
37
+ <gd:rating average="8.0" max="10" min="0" numRaters="50"/>
38
+ </entry>}
39
+ end
40
+
41
+ it "should correct deserialize from string" do
42
+ subject = Subject.new(@s)
43
+ subject.id.should == "http://api.douban.com/book/subject/1088840"
44
+ subject.subject_id.should == 1088840
45
+ subject.title.should == "无机化学(下)/高等学校教材"
46
+ subject.category.should == {"term"=>"http://www.douban.com/2007#book", "scheme"=>"http://www.douban.com/2007#kind"}
47
+ subject.author.class.should == Author
48
+ subject.link.should == {"self"=>"http://api.douban.com/book/subject/1088840",
49
+ "alternate"=>"http://book.douban.com/subject/1088840/",
50
+ "image"=>"http://img2.douban.com/spic/s1075910.jpg",
51
+ "collection"=>"http://api.douban.com/collection/266907549"}
52
+ subject.summary.should == nil
53
+ subject.attribute.should == {"pubdate"=>"2005-1-1", "price"=>"26.5", "isbn10"=>"7040048809", "title"=>"无机化学(下)/高等学校教\346\235\220", "author"=>"武汉大学、吉林大\345\255\246", "isbn13"=>"9787040048803", "publisher"=>"高等教育出版社",
54
+ "pages"=>"1185", "binding"=>"平装"}
55
+ subject.tag.size.should == 8
56
+ subject.tag[0].class.should == Tag
57
+ subject.rating.should == {"max"=>"10", "average"=>"8.0", "min"=>"0", "numRaters"=>"50"}
58
+ end
59
+
60
+ it "should support ==" do
61
+ Subject.new(@s).should == Subject.new(@s)
62
+ end
63
+
64
+ it "should correct deserialize from REXML::Document" do
65
+ Subject.new(REXML::Document.new(@s)).should == Subject.new(@s)
66
+ end
67
+
68
+ it "should correct deserialize from REXML::Element" do
69
+ Subject.new(REXML::Document.new(@s).root).should == Subject.new(@s)
70
+ end
71
+
72
+ context "book" do
73
+ it "should support isbn" do
74
+ book = Book.new(@s)
75
+ book.isbn10.should == "7040048809"
76
+ book.isbn13.should == "9787040048803"
77
+ book.isbn.should == book.isbn13
78
+ end
79
+ end
80
+
81
+ context "movie" do
82
+ before do
83
+ @s_movie = %Q{<?xml version="1.0" encoding="UTF-8"?>
84
+ <entry xmlns="http://www.w3.org/2005/Atom" xmlns:db="http://www.douban.com/xmlns/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:opensearch="http://a9.com/-/spec/opensearchrss/1.0/">
85
+ <id>http://api.douban.com/movie/subject/1858711</id>
86
+ <title>Toy Story 3</title>
87
+ <category scheme="http://www.douban.com/2007#kind" term="http://www.douban.com/2007#movie"/>
88
+ <author>
89
+ <name>Lee Unkrich</name>
90
+ </author>
91
+ <link href="http://api.douban.com/movie/subject/1858711" rel="self"/>
92
+ <link href="http://movie.douban.com/subject/1858711/" rel="alternate"/>
93
+ <link href="http://t.douban.com/spic/s4207957.jpg" rel="image"/>
94
+ <summary>自从11年前玩具们所经历的大冒险后,玩具们安然无恙的度过了好几个年头。转眼间,玩具们的主人安迪(约翰·莫里斯 John Morris 配音)已经成为一个青少年,也即将离家去展开他的大学生涯。伍迪(汤姆·汉克斯 Tom Hanks 配音)与巴斯(蒂姆·艾伦 Tim Allen 配音)以及其他的玩具们也都人心惶惶,深怕这个他们内心最恐惧被丢弃的一天即将来临。这一天,安迪的妈妈来到安迪的房间,询问他将如何处置这些伴他渡过童年的玩具们,并且要求安迪在离家前要把这些东西处理好,如果没有将要留下的玩具放置阁楼收藏,她就会把这些玩具处理掉。安迪在妈妈的逼迫下,再次打开他的玩具箱,童年回忆涌上心头,他根本舍不得将任何一件玩具丢掉,所以将所有的玩具都放入大黑袋子中,准备将它们放置阁楼,但正要将袋子放入阁楼的同时,安迪被妹妹呼唤去帮忙,就在阴错阳差之下,妈妈误以为黑袋子里的玩具是要丢弃,所以就将玩具们全数捐给阳光托儿所。
95
+ 玩具们来到阳光托儿所原本以为来到了天堂,托儿所里有非常好的规划还有更多玩具的新朋友,而且玩具们也都兴奋的期待能够再与小主人一同玩乐。殊不知托儿所的小朋友一抵达教室的时候才是噩梦的开始,被拉扯、被吞食、被支解几乎是天天上演的戏码。另外托儿所还有黑暗的地下组织,玩具们人人自危。
96
+ 同时安迪发现珍藏的玩具被不心丢弃了,正心急如焚的寻找,玩具们得知小主人安迪在寻找他们,即将一起展开史上最大规模的逃亡行动,还有更多的冒险等着他们,玩具们是否能成功回到小主人安迪的身边呢?
97
+ 本片在视听效果上全面追赶潮流,大规模投放3D版本。此外,本片还成为了杜比7.1版本音响系统第一部应用的影片。</summary>
98
+ <db:attribute name="country">美国</db:attribute>
99
+ <db:attribute name="website">http://disney.go.com/toystory/</db:attribute>
100
+ <db:attribute name="writer">Michael Arndt</db:attribute>
101
+ <db:attribute name="writer">John Lasseter</db:attribute>
102
+ <db:attribute name="title">Toy Story 3</db:attribute>
103
+ <db:attribute name="director">Lee Unkrich</db:attribute>
104
+ <db:attribute lang="zh_CN" name="aka">玩具总动员3</db:attribute>
105
+ <db:attribute name="pubdate">2010-06-16 (中国大陆)</db:attribute>
106
+ <db:attribute name="imdb">http://www.imdb.com/title/tt0435761/</db:attribute>
107
+ <db:attribute name="language">英语</db:attribute>
108
+ <db:attribute name="language">西班牙语</db:attribute>
109
+ <db:attribute name="cast">Tom Hanks</db:attribute>
110
+ <db:attribute name="cast">Tim Allen</db:attribute>
111
+ <db:attribute name="cast">Joan Cusack</db:attribute>
112
+ <db:attribute name="cast">Ned Beatty</db:attribute>
113
+ <db:attribute name="cast">Don Rickles</db:attribute>
114
+ <db:attribute name="cast">Michael Keaton</db:attribute>
115
+ <db:attribute name="aka">反斗奇兵3</db:attribute>
116
+ <db:attribute name="aka">玩具总动员3</db:attribute>
117
+ <db:tag count="6515" name="动画"/>
118
+ <db:tag count="4202" name="Pixar"/>
119
+ <db:tag count="3054" name="美国"/>
120
+ <db:tag count="2653" name="3D"/>
121
+ <db:tag count="2003" name="迪斯尼"/>
122
+ <db:tag count="1123" name="2010"/>
123
+ <db:tag count="963" name="成长"/>
124
+ <db:tag count="879" name="喜剧"/>
125
+ <gd:rating average="9.1" max="10" min="0" numRaters="18675"/>
126
+ </entry>}
127
+ end
128
+
129
+ it "should support imdb" do
130
+ movie = Movie.new(@s_movie)
131
+ movie.imdb.should == "tt0435761"
132
+ end
133
+ end
134
+ end
135
+ end
136
+
metadata CHANGED
@@ -5,12 +5,12 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 0
8
- - 5
9
- version: 0.0.5
8
+ - 6
9
+ version: 0.0.6
10
10
  platform: ruby
11
11
  authors:
12
- - Hoooopo
13
12
  - LI Daobing
13
+ - Hoooopo
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain:
@@ -36,13 +36,25 @@ cert_chain:
36
36
  odexk8E9/2c=
37
37
  -----END CERTIFICATE-----
38
38
 
39
- date: 2010-07-05 00:00:00 +08:00
39
+ date: 2010-07-10 00:00:00 +08:00
40
40
  default_executable:
41
41
  dependencies:
42
42
  - !ruby/object:Gem::Dependency
43
- name: rubyforge
43
+ name: oauth
44
44
  prerelease: false
45
45
  requirement: &id001 !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ segments:
50
+ - 0
51
+ version: "0"
52
+ type: :runtime
53
+ version_requirements: *id001
54
+ - !ruby/object:Gem::Dependency
55
+ name: rubyforge
56
+ prerelease: false
57
+ requirement: &id002 !ruby/object:Gem::Requirement
46
58
  requirements:
47
59
  - - ">="
48
60
  - !ruby/object:Gem::Version
@@ -52,11 +64,11 @@ dependencies:
52
64
  - 4
53
65
  version: 2.0.4
54
66
  type: :development
55
- version_requirements: *id001
67
+ version_requirements: *id002
56
68
  - !ruby/object:Gem::Dependency
57
69
  name: hoe
58
70
  prerelease: false
59
- requirement: &id002 !ruby/object:Gem::Requirement
71
+ requirement: &id003 !ruby/object:Gem::Requirement
60
72
  requirements:
61
73
  - - ">="
62
74
  - !ruby/object:Gem::Version
@@ -66,14 +78,14 @@ dependencies:
66
78
  - 1
67
79
  version: 2.6.1
68
80
  type: :development
69
- version_requirements: *id002
81
+ version_requirements: *id003
70
82
  description: |-
71
83
  douban ruby client. including OAuth support.
72
84
 
73
85
  Douban API reference: http://www.douban.com/service/apidoc/reference/
74
86
  email:
75
- - hoooopo@gmail.com
76
87
  - lidaobing@gmail.com
88
+ - hoooopo@gmail.com
77
89
  executables: []
78
90
 
79
91
  extensions: []
@@ -96,7 +108,10 @@ files:
96
108
  - lib/douban/event.rb
97
109
  - lib/douban/mail.rb
98
110
  - lib/douban/miniblog.rb
111
+ - lib/douban/miniblog_comment.rb
112
+ - lib/douban/miniblog_comments.rb
99
113
  - lib/douban/note.rb
114
+ - lib/douban/page_info.rb
100
115
  - lib/douban/people.rb
101
116
  - lib/douban/recommendation.rb
102
117
  - lib/douban/recommendation_comment.rb
@@ -108,12 +123,16 @@ files:
108
123
  - spec/douban/collection_spec.rb
109
124
  - spec/douban/event_spec.rb
110
125
  - spec/douban/mail_spec.rb
126
+ - spec/douban/miniblog_comment_spec.rb
127
+ - spec/douban/miniblog_comments_spec.rb
111
128
  - spec/douban/miniblog_spec.rb
112
129
  - spec/douban/note_spec.rb
130
+ - spec/douban/page_info_spec.rb
113
131
  - spec/douban/people_spec.rb
114
132
  - spec/douban/recommendation_comment_spec.rb
115
133
  - spec/douban/recommendation_spec.rb
116
134
  - spec/douban/review_spec.rb
135
+ - spec/douban/subject_spec.rb
117
136
  - spec/douban/tag_spec.rb
118
137
  - spec/douban_spec.rb
119
138
  - spec/spec_helper.rb
metadata.gz.sig CHANGED
Binary file