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 +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
|