C0 code coverage information
Generated on Tue Oct 16 11:40:48 -0400 2007 with rcov 0.8.0
Code reported as executed by Ruby looks like this...
and this: this line is also marked as covered.
Lines considered as run by rcov, but not reported by Ruby, look like this,
and this: these lines were inferred by rcov (using simple heuristics).
Finally, here's a line marked as not executed.
1 # Copyright (C) 2007 Marco Costantini
2 # based on ibs_it.rb by Claudio Belotti
3 #
4 # Alexandria is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 2 of the
7 # License, or (at your option) any later version.
8 #
9 # Alexandria is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public
15 # License along with Alexandria; see the file COPYING. If not,
16 # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 # Boston, MA 02111-1307, USA.
18
19 require 'fileutils'
20 require 'net/http'
21 require 'open-uri'
22 #require 'cgi'
23
24 module Alexandria
25 class BookProviders
26 class Webster_itProvider < GenericProvider
27 BASE_URI = "http://www.libreriauniversitaria.it" # also "http://www.webster.it"
28 CACHE_DIR = File.join(Alexandria::Library::DIR, '.webster_it_cache')
29 REFERER = BASE_URI
30 LOCALE = "BIT" # used only for search by title/author/keyword. possible are: "BIT", "BUS", "BUK", "BDE", "MIT"
31 def initialize
32 super("Webster_it", "Webster (Italy)")
33 FileUtils.mkdir_p(CACHE_DIR) unless File.exists?(CACHE_DIR)
34 # no preferences for the moment
35 at_exit { clean_cache }
36 end
37
38 def search(criterion, type)
39 criterion = criterion.convert("ISO-8859-15", "UTF-8")
40 req = BASE_URI + "/"
41 req += case type
42 when SEARCH_BY_ISBN
43 "isbn/" # "#{LOCALE}/"
44
45 when SEARCH_BY_TITLE
46 "c_search.php?noinput=1&shelf=#{LOCALE}&title_query="
47
48 when SEARCH_BY_AUTHORS
49 "c_search.php?noinput=1&shelf=#{LOCALE}&author_query="
50
51 when SEARCH_BY_KEYWORD
52 "c_search.php?noinput=1&shelf=#{LOCALE}&subject_query="
53
54 else
55 raise InvalidSearchTypeError
56
57 end
58
59 req += CGI.escape(criterion)
60 p req if $DEBUG
61 data = transport.get(URI.parse(req))
62 if type == SEARCH_BY_ISBN
63 to_book(data) #rescue raise NoResultsError
64 else
65 begin
66 results = []
67 each_book_page(data) do |code, title|
68 results << to_book(transport.get(URI.parse(BASE_URI + "/#{LOCALE}/" + code)))
69 end
70 return results
71 rescue
72 raise NoResultsError
73 end
74 end
75 end
76
77 def url(book)
78 BASE_URI + "/isbn/" + book.isbn
79 end
80
81 #######
82 private
83 #######
84
85 def to_book(data)
86 raise NoResultsError if /<font color="\#ffffff"><b>Prodotto non esistente<\/b><\/font>/.match(data) != nil
87 data = data.convert("UTF-8", "ISO-8859-15")
88
89 raise unless md = /<li><span class="product_label">Titolo:<\/span><span class="product_text"> ([^<]+)/.match(data)
90 title = CGI.unescape(md[1].strip)
91 if md = /<span class="product_heading_volume">([^<]+)/.match(data)
92 title += " " + CGI.unescape(md[1].strip)
93 end
94
95 authors = []
96 if md = /<li><span class="product_label">Autor[ei]:<\/span> <span class="product_text">(<a href="[^>]+">([^<]+)<\/a>,? ?)+<\/span><li>/.match(data)
97 this = CGI.unescape(md[0].strip)
98 authors = this.scan(/<a href="[^>]+">([^<]+)<\/a>,?/)
99 authors = authors.collect {|author| author[0]}
100 #puts this
101 # md[1].strip.split(', ').each { |a| authors << CGI.unescape(a.strip) }
102 end
103
104 raise unless md = /<li><span class="product_label">ISBN:<\/span> <span class="product_text">([^<]+)/.match(data)
105 isbn = Library.canonicalise_ean( md[1].strip )
106
107 #raise unless
108 md = /<li><span class="product_label">Editore:<\/span> <span class="product_text"><a href="[^>]+>([^<]+)/.match(data)
109 publisher = CGI.unescape(md[1].strip) or md
110
111 if md = /<li><span class="product_label">Pagine:<\/span> <span class="product_text">([^<]+)/.match(data)
112 edition = CGI.unescape(md[1].strip) + " p."
113 else
114 edition = nil
115 end
116
117 publish_year = nil
118 if md = /<li><span class="product_label">Data di Pubblicazione:<\/span> <span class="product_text">([^<]+)/.match(data)
119 publish_year = CGI.unescape(md[1].strip)[-4 .. -1].to_i
120 publish_year = nil if publish_year == 0
121 end
122
123 if data =~ /javascript:popImage/ and md = /<img border="0" alt="[^"]+" src="([^"]+)/.match(data)
124 cover_url = BASE_URI + md[1].strip
125 # use "p" instead of "g" for smaller image
126 if cover_url[-5] == 103
127 cover_url[-5] = 112
128 end
129
130 cover_filename = isbn + ".tmp"
131 Dir.chdir(CACHE_DIR) do
132 File.open(cover_filename, "w") do |file|
133 file.write open(cover_url, "Referer" => REFERER ).read rescue nil
134 end
135 end
136
137 medium_cover = CACHE_DIR + "/" + cover_filename
138 if File.size(medium_cover) > 0
139 puts medium_cover + " has non-0 size" if $DEBUG
140 return [ Book.new(title, authors, isbn, publisher, publish_year, edition),medium_cover ]
141 end
142 puts medium_cover + " has 0 size, removing ..." if $DEBUG
143 File.delete(medium_cover)
144 end
145 return [ Book.new(title, authors, isbn, publisher, publish_year, edition) ]
146 end
147
148 def each_book_page(data)
149 raise if data.scan(/<tr ><td width="10%" align="center""> <a href="#{LOCALE}\/([^\/]+)/) { |a| yield a}.empty?
150 end
151
152 def clean_cache
153 #FIXME begin ... rescue ... end?
154 Dir.chdir(CACHE_DIR) do
155 Dir.glob("*.tmp") do |file|
156 puts "removing " + file if $DEBUG
157 File.delete(file)
158 end
159 end
160 end
161 end
162 end
163 end
Generated using the rcov code coverage analysis tool for Ruby version 0.8.0.