doubapi 0.0.9 → 0.1.0
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/README +21 -12
- data/lib/doubapi/version.rb +1 -1
- data/lib/doubapi.rb +122 -53
- data/lib/test.rb +55 -20
- metadata +2 -2
data/README
CHANGED
@@ -1,20 +1,29 @@
|
|
1
1
|
Usage:
|
2
2
|
require 'doubapi'
|
3
3
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
4
|
+
|
5
|
+
Release NOTES:
|
6
|
+
1.2012/7/17: v0.1.0: The API have been changed in 0.1.0 release and it is not backward compatible.
|
7
|
+
|
8
|
+
Previously:
|
9
|
+
|
10
|
+
Doubapi.search_events_of("all").each do |event|
|
11
|
+
puts event.title
|
12
|
+
puts event.when
|
13
|
+
puts event.where
|
14
|
+
puts event.link
|
10
15
|
end
|
11
16
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
After 0.1.0
|
18
|
+
|
19
|
+
Doubapi.search_events_of(:key => "all", :location => "shanghai", :start_index => 1,:max_result => 30) do |event|
|
20
|
+
puts event.title
|
21
|
+
puts event.when
|
22
|
+
puts event.where
|
23
|
+
puts event.link
|
18
24
|
end
|
19
25
|
|
20
26
|
|
27
|
+
check lib/test.rb for more usage.
|
28
|
+
|
29
|
+
|
data/lib/doubapi/version.rb
CHANGED
data/lib/doubapi.rb
CHANGED
@@ -1,29 +1,65 @@
|
|
1
|
+
#
|
2
|
+
# Copyright (c) 2009-2012 pierr.chen at gmail dot com
|
3
|
+
#
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
# a copy of this software and associated documentation files (the
|
6
|
+
# "Software"), to deal in the Software without restriction, including
|
7
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
# the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be
|
13
|
+
# included in all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
|
+
#
|
23
|
+
|
1
24
|
require 'RUBYgems' #a hack to require failure for nokogiri
|
2
25
|
require 'open-uri'
|
3
26
|
require 'nokogiri'
|
4
27
|
require 'pp'
|
5
28
|
|
6
29
|
|
30
|
+
#useful information:
|
31
|
+
#when accessing the the Nokogiri parsed result, all the name are downcase-d
|
32
|
+
#for example : to access the totalResults element
|
33
|
+
#<openSearch:totalResults>111</openSearch:totalResults>
|
34
|
+
#you should use doc.at_xpath(".//totalresults")
|
35
|
+
|
36
|
+
#at_xpath is to return single element and you know only there is only one element.
|
37
|
+
#xpath is to return an array of elements
|
38
|
+
|
7
39
|
module Doubapi
|
8
40
|
#return a Nokogiri XML object
|
9
41
|
#use Douban API
|
10
|
-
|
11
|
-
|
12
|
-
Event = Struct.new :title, :when, :where, :what, :link
|
42
|
+
Event = Struct.new :title, :when, :where, :what,:link,:poster_mobile,:bar_icon
|
13
43
|
#release_date is in the format of YY-MM-DD
|
14
|
-
Album = Struct.new :author, :title, :release_date,
|
44
|
+
Album = Struct.new :author, :title, :release_date, :link,:cover_thumbnail,:publisher,:mobile_site
|
15
45
|
|
16
46
|
#input:{key => "all/singer_name", :location => "shanghai", :start_index => 16,:max_result => 15}
|
17
|
-
#return
|
18
|
-
|
19
|
-
|
47
|
+
#return total number of events satisfying the search criterion
|
48
|
+
#Doubapi::Event[]
|
49
|
+
def self.search_events_of h ,&block
|
50
|
+
totalResult, returnedResult = Douban.search_events_of h
|
51
|
+
returnedResult.each {|event| block.call(event) if block_given?}
|
52
|
+
return totalResult;
|
20
53
|
end
|
21
54
|
|
22
55
|
|
23
56
|
#input {:singer,:since}
|
57
|
+
#return total number of events satisfying the search criterion
|
24
58
|
#return Doubapi::Album[]
|
25
|
-
def self.search_albums_of h
|
26
|
-
Douban.search_albums_of h
|
59
|
+
def self.search_albums_of h ,&block
|
60
|
+
totalResult, returnedResult = Douban.search_albums_of h
|
61
|
+
returnedResult.each {|album| block.call(album) if block_given?}
|
62
|
+
return totalResult;
|
27
63
|
end
|
28
64
|
|
29
65
|
protected
|
@@ -34,13 +70,19 @@ class << self
|
|
34
70
|
def douban_get_xml url
|
35
71
|
puts url
|
36
72
|
#I have forgot why i need to specify the user agend
|
37
|
-
|
38
|
-
|
39
|
-
|
73
|
+
doc = open(url, :proxy => nil, 'User-Agent' => 'ruby')
|
74
|
+
if doc.nil?
|
75
|
+
puts "error:failed to open #{url}"
|
76
|
+
return nil;
|
77
|
+
end
|
78
|
+
|
79
|
+
Nokogiri::HTML(doc,nil, "utf-8")
|
80
|
+
|
81
|
+
#Nokogiri::HTML(open(url,:proxy => nil,'User-Agent' => 'ruby'),nil, "utf-8")
|
40
82
|
#no network access, used to simulator
|
41
83
|
#doc = File.read(File.join(RAILS_ROOT, "app","controllers","event_sample.xml"))
|
42
84
|
#Nokogiri::HTML(doc,nil, "utf-8")
|
43
|
-
|
85
|
+
#Nokogiri::HTML(open(url,:proxy => nil,'User-Agent' => 'ruby'),nil, "utf-8")
|
44
86
|
end
|
45
87
|
|
46
88
|
|
@@ -107,45 +149,64 @@ def compare_date a , b
|
|
107
149
|
return true if (ya.to_i * 12 + ma.to_i ) >= (yb.to_i*12+mb.to_i)
|
108
150
|
end
|
109
151
|
|
152
|
+
|
153
|
+
def formate_release_date release_date
|
154
|
+
#make release data YY-MM-DD style
|
155
|
+
r = release_date.scan(/\d{1,4}/)
|
156
|
+
#if DD was not specified
|
157
|
+
r << "01" if r.size == 2
|
158
|
+
r << "01" << "01" if r.size == 1
|
159
|
+
|
160
|
+
y , m , d = r
|
161
|
+
|
162
|
+
m = "01" unless (1..12).include?(m.to_i)
|
163
|
+
d = "01" unless (1..30).include?(d.to_i)
|
164
|
+
|
165
|
+
"#{y}-#{m}-#{d}"
|
166
|
+
end
|
167
|
+
|
168
|
+
|
169
|
+
#
|
170
|
+
#search albums tagged with h[:singer]. It is not quite accurate. I have seen some irrevlant result are returned.
|
171
|
+
#
|
172
|
+
#
|
110
173
|
def search_albums_of h
|
111
174
|
artist = h[:singer]
|
112
175
|
after_date = h[:since]||"1900.01"
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
end
|
148
|
-
albums
|
176
|
+
doc = search_ablum h
|
177
|
+
|
178
|
+
if(doc.nil?)
|
179
|
+
return [0,[]];
|
180
|
+
end
|
181
|
+
|
182
|
+
#the totalResult here trying
|
183
|
+
#totalResults = doc.at_xpath(".//totalresults").text.to_i
|
184
|
+
|
185
|
+
albums=[]
|
186
|
+
doc.xpath("//entry").each do |entry|
|
187
|
+
title = entry.at_xpath(".//title").text
|
188
|
+
#author
|
189
|
+
authorItem = entry.at_xpath(".//name")
|
190
|
+
author = if authorItem.nil? then artist else authorItem.text end
|
191
|
+
#link - pc web
|
192
|
+
link = entry.at_xpath(".//link[@rel='alternate']")["href"]
|
193
|
+
cover_thumnail = entry.at_xpath(".//link[@rel='image']")["href"]
|
194
|
+
#publisher
|
195
|
+
pubItem = entry.at_xpath(".//attribute[@name='publisher']")
|
196
|
+
publisher = if pubItem.nil? then "unknow" else pubItem.text end
|
197
|
+
#link - mobile_site
|
198
|
+
mobile_site = entry.at_xpath(".//link[@rel='mobile']")["href"]
|
199
|
+
#release_date
|
200
|
+
pubDateItem = entry.at_xpath(".//attribute[@name='pubdate']")
|
201
|
+
release_date = if pubDateItem.nil? then "0000-00" else pubDateItem.text end
|
202
|
+
formated_release_day = formate_release_date(release_date)
|
203
|
+
#check the release date
|
204
|
+
if compare_date release_date, after_date
|
205
|
+
albums << Doubapi::Album.new(author, title, formated_release_day, link, cover_thumnail,publisher,mobile_site)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
#improve ME
|
209
|
+
[albums.size,albums]
|
149
210
|
end
|
150
211
|
|
151
212
|
|
@@ -160,12 +221,13 @@ end
|
|
160
221
|
end
|
161
222
|
|
162
223
|
def search_events_of(h={})
|
163
|
-
|
164
|
-
puts h.inspect
|
165
224
|
artist = h[:key]
|
166
225
|
after_date = h[:after_date]||Time.now.strftime("%Y-%m")
|
167
226
|
doc = search_event h
|
168
227
|
events=[]
|
228
|
+
|
229
|
+
#NOTES:all the key will be downcase-d
|
230
|
+
totalResults = doc.at_xpath(".//totalresults").text.to_i
|
169
231
|
doc.xpath("//entry").each do |entry|
|
170
232
|
#pp entry
|
171
233
|
title = entry.at_xpath(".//title").text
|
@@ -175,15 +237,22 @@ def search_events_of(h={})
|
|
175
237
|
where = entry.at_xpath('.//where')["valuestring"]
|
176
238
|
link = entry.at_xpath(".//link[@rel='alternate']")["href"]
|
177
239
|
what = entry.at_xpath(".//content").text
|
240
|
+
posterItem = entry.at_xpath(".//link[@rel='image-lmobile']")
|
241
|
+
poster_mobile = if posterItem.nil? then "empty" else posterItem["href"] end
|
242
|
+
authItem = entry.at_xpath(".//author")
|
243
|
+
iconLink = if authItem.nil? then nil else authItem.at_xpath(".//link[@rel='icon']") end
|
244
|
+
bar_icon = if (iconLink.nil?) then nil else iconLink["href"] end
|
178
245
|
|
179
246
|
#check the date
|
180
247
|
if parse_date(start_time) > parse_date(after_date)
|
181
|
-
events << Doubapi::Event.new(title, start_time, where, what, link)
|
248
|
+
events << Doubapi::Event.new(title, start_time, where, what, link, poster_mobile, bar_icon)
|
182
249
|
end
|
183
250
|
end
|
184
251
|
|
185
252
|
#filtering of the results
|
186
|
-
events.select{|e| looks_like_a_live_show?(e,artist)}
|
253
|
+
events.select!{|e| looks_like_a_live_show?(e,artist)}
|
254
|
+
|
255
|
+
[totalResults, events]
|
187
256
|
end
|
188
257
|
|
189
258
|
end #self,instance method end
|
data/lib/test.rb
CHANGED
@@ -19,44 +19,79 @@ end
|
|
19
19
|
|
20
20
|
def test2
|
21
21
|
author = "李志"
|
22
|
-
Doubapi.search_albums_of(:singer=>author,:since=>"2010-05")
|
22
|
+
Doubapi.search_albums_of(:singer=>author,:since=>"2010-05") do |album|
|
23
|
+
puts "-------------------------------"
|
23
24
|
puts album.author
|
24
25
|
puts album.release_date
|
25
26
|
puts album.title
|
27
|
+
puts album.cover_thumbnail
|
28
|
+
puts album.publisher
|
26
29
|
puts album.link
|
30
|
+
puts album.mobile_site
|
27
31
|
end
|
28
32
|
end
|
29
33
|
|
30
34
|
|
31
35
|
|
32
|
-
def
|
36
|
+
def test_get_all_events
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
38
|
+
|
39
|
+
puts "trying to get 30 first"
|
40
|
+
|
41
|
+
batch_size = 30;
|
42
|
+
totalResults1 = Doubapi.search_events_of(:key => "all", :location => "shanghai", :start_index => 1,:max_result => batch_size) do |event|
|
43
|
+
# puts "#{event.when} #{event.title}"
|
39
44
|
end
|
40
45
|
|
41
|
-
puts "
|
46
|
+
puts "total results #{totalResults1} ,will fetch others"
|
42
47
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
48
|
+
return if(totalResults1 <= batch_size)
|
49
|
+
|
50
|
+
(2..totalResults1/batch_size).each do |i|
|
51
|
+
start_index = (i-1)*batch_size+1;
|
52
|
+
max_result = batch_size;
|
53
|
+
puts "start_index :#{start_index}"
|
54
|
+
Doubapi.search_events_of(:key => "all", :location => "shanghai", :start_index => start_index, :max_result => max_result) do |event|
|
55
|
+
# puts "#{event.when} #{event.title}"
|
56
|
+
end
|
57
|
+
|
47
58
|
end
|
48
59
|
|
49
|
-
|
60
|
+
return if((totalResults1%batch_size)==0)
|
50
61
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
62
|
+
last_fetch_size = totalResults1 - (totalResults1/batch_size)*batch_size;
|
63
|
+
|
64
|
+
start_index = (totalResults1/batch_size)*batch_size+1;
|
65
|
+
max_result = last_fetch_size;
|
66
|
+
puts "start_index :#{start_index}"
|
67
|
+
Doubapi.search_events_of(:key => "all", :location => "shanghai", :start_index => start_index, :max_result => max_result) do |event|
|
68
|
+
# puts "#{event.when} #{event.title}"
|
55
69
|
end
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
|
56
77
|
end
|
57
78
|
|
58
79
|
|
59
|
-
|
60
|
-
|
61
|
-
|
80
|
+
def test4
|
81
|
+
|
82
|
+
totalResults = Doubapi.search_events_of(:key => "all", :location => "shanghai", :start_index => 1,:max_result => 1) do |event|
|
83
|
+
puts "#{event.when} #{event.title}"
|
84
|
+
puts event.where
|
85
|
+
puts event.link
|
86
|
+
puts event.poster_mobile
|
87
|
+
puts event.bar_icon
|
88
|
+
end
|
89
|
+
|
90
|
+
puts "totalResults #{totalResults}"
|
91
|
+
|
92
|
+
end
|
62
93
|
|
94
|
+
test_get_all_events
|
95
|
+
#test1
|
96
|
+
#test2
|
97
|
+
#test4
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doubapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-07-
|
12
|
+
date: 2012-07-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|