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.
Files changed (5) hide show
  1. data/README +21 -12
  2. data/lib/doubapi/version.rb +1 -1
  3. data/lib/doubapi.rb +122 -53
  4. data/lib/test.rb +55 -20
  5. metadata +2 -2
data/README CHANGED
@@ -1,20 +1,29 @@
1
1
  Usage:
2
2
  require 'doubapi'
3
3
 
4
- key = "许巍"
5
- Doubapi.search_events_of(key).each do |event|
6
- puts event.title
7
- puts event.when
8
- puts event.where
9
- puts event.link
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
- author = "李志"
13
- Doubapi.search_albums_of(author, "2010-05").each do |album|
14
- puts album.author
15
- puts album.release_date
16
- puts album.title
17
- puts album.link
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
+
@@ -1,3 +1,3 @@
1
1
  module Doubapi
2
- VERSION = "0.0.9"
2
+ VERSION = "0.1.0"
3
3
  end
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, :link
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 Doubapi::Event[]
18
- def self.search_events_of h
19
- Douban.search_events_of h
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
- doc = open(url, :proxy => nil, 'User-Agent' => 'ruby')
38
- Nokogiri::HTML(doc,nil, "utf-8")
39
- #Nokogiri::HTML(open(url,:proxy => nil,'User-Agent' => 'ruby'),nil, "utf-8")
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
- #Nokogiri::HTML(open(url,:proxy => nil,'User-Agent' => 'ruby'),nil, "utf-8")
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
- doc = search_ablum h
114
- albums=[]
115
-
116
- doc.xpath("//entry").each do |entry|
117
- title = entry.at_xpath(".//title").text
118
- author = unless entry.at_xpath(".//name").nil?
119
- entry.at_xpath(".//name").text
120
- else
121
- "unknown(#{artist}?)"
122
- end
123
- release_date = unless entry.at_xpath(".//attribute[@name='pubdate']").nil?
124
- entry.at_xpath(".//attribute[@name='pubdate']").text
125
- else
126
- #means unknow
127
- "0000-00"
128
- end
129
- link = entry.at_xpath(".//link[@rel='alternate']")["href"]
130
-
131
- #make release data YY-MM-DD style
132
- r = release_date.scan(/\d{1,4}/)
133
- #if DD was not specified
134
- r << "01" if r.size == 2
135
- r << "01" << "01" if r.size == 1
136
-
137
- y , m , d = r
138
-
139
- m = "01" unless (1..12).include?(m.to_i)
140
- d = "01" unless (1..30).include?(d.to_i)
141
-
142
- formated_release_day = "#{y}-#{m}-#{d}"
143
- #check the release date
144
- if compare_date release_date, after_date
145
- albums << Doubapi::Album.new(author, title, formated_release_day, link)
146
- end
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").each do |album|
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 test3
36
+ def test_get_all_events
33
37
 
34
- puts "1-30"
35
- Doubapi.search_events_of(:key => "all", :location => "shanghai", :start_index => 1,:max_result => 30).each do |event|
36
- puts "#{event.when} #{event.title}"
37
- #puts event.where
38
- #puts event.link
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 "1-15"
46
+ puts "total results #{totalResults1} ,will fetch others"
42
47
 
43
- Doubapi.search_events_of(:key => "all", :location => "shanghai", :start_index => 1,:max_result => 15).each do |event|
44
- puts "#{event.when} #{event.title}"
45
- #puts event.where
46
- #puts event.link
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
- puts "16-30"
60
+ return if((totalResults1%batch_size)==0)
50
61
 
51
- Doubapi.search_events_of(:key => "all", :location => "shanghai", :start_index => 16,:max_result => 15).each do |event|
52
- puts "#{event.when} #{event.title}"
53
- #puts event.where
54
- #puts event.link
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
- #test3
60
- #test1
61
- test2
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.9
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-11 00:00:00.000000000 Z
12
+ date: 2012-07-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec