douban-ruby 0.0.5 → 0.0.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.
- data.tar.gz.sig +0 -0
- data/History.txt +13 -0
- data/Manifest.txt +7 -0
- data/Rakefile +7 -1
- data/examples/example.rb +4 -2
- data/lib/douban.rb +1 -1
- data/lib/douban/authorize.rb +198 -18
- data/lib/douban/miniblog.rb +19 -15
- data/lib/douban/miniblog_comment.rb +42 -0
- data/lib/douban/miniblog_comments.rb +31 -0
- data/lib/douban/page_info.rb +23 -0
- data/lib/douban/subject.rb +48 -16
- data/spec/douban/authorize_spec.rb +80 -12
- data/spec/douban/miniblog_comment_spec.rb +42 -0
- data/spec/douban/miniblog_comments_spec.rb +66 -0
- data/spec/douban/miniblog_spec.rb +1 -0
- data/spec/douban/page_info_spec.rb +26 -0
- data/spec/douban/subject_spec.rb +136 -0
- metadata +28 -9
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
@@ -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
|
data/Manifest.txt
CHANGED
@@ -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
|
data/examples/example.rb
CHANGED
data/lib/douban.rb
CHANGED
data/lib/douban/authorize.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
147
|
-
|
148
|
-
|
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
|
-
|
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
|
-
|
160
|
-
|
161
|
-
|
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
|
-
|
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
|
-
|
182
|
-
|
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
|
-
|
197
|
-
|
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
|
-
|
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
|
|
data/lib/douban/miniblog.rb
CHANGED
@@ -4,20 +4,20 @@ require 'douban/author'
|
|
4
4
|
require 'douban/equal'
|
5
5
|
|
6
6
|
module Douban
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
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
|
data/lib/douban/subject.rb
CHANGED
@@ -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
|
-
|
26
|
-
doc =
|
27
|
-
|
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,"
|
37
|
+
title=REXML::XPath.first(doc,"./title")
|
30
38
|
@title=title.text if title
|
31
39
|
@category={}
|
32
|
-
category=REXML::XPath.first(doc,"
|
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,"
|
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,"
|
51
|
+
name=REXML::XPath.first(doc,"./author/name")
|
44
52
|
@author.name=name.text if name
|
45
|
-
uri=REXML::XPath.first(doc,"
|
53
|
+
uri=REXML::XPath.first(doc,"./author/uri")
|
46
54
|
@author.uri=uri.text if uri
|
47
|
-
REXML::XPath.each(doc,"
|
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,"
|
59
|
+
summary=REXML::XPath.first(doc,"./summary")
|
52
60
|
@summary=summary.text if summary
|
53
|
-
REXML::XPath.each(doc,"
|
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,"
|
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,"
|
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
|
-
|
70
|
-
|
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
|
-
|
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 = '
|
65
|
-
@access_secret = '
|
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 ==
|
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
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
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
|
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
|
-
-
|
9
|
-
version: 0.0.
|
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-
|
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:
|
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: *
|
67
|
+
version_requirements: *id002
|
56
68
|
- !ruby/object:Gem::Dependency
|
57
69
|
name: hoe
|
58
70
|
prerelease: false
|
59
|
-
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: *
|
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
|