alexandria-book-collection-manager 0.6.9 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +34 -30
- data/.rubocop_todo.yml +139 -54
- data/CHANGELOG.md +10 -0
- data/Gemfile +1 -0
- data/Rakefile +10 -11
- data/alexandria-book-collection-manager.gemspec +3 -2
- data/bin/alexandria +1 -1
- data/lib/alexandria.rb +3 -6
- data/lib/alexandria/about.rb +9 -9
- data/lib/alexandria/book_providers.rb +12 -12
- data/lib/alexandria/book_providers/adlibris.rb +14 -18
- data/lib/alexandria/book_providers/amazon_aws.rb +17 -31
- data/lib/alexandria/book_providers/amazon_ecs_util.rb +5 -6
- data/lib/alexandria/book_providers/barnes_and_noble.rb +51 -76
- data/lib/alexandria/book_providers/bol_it.rb +12 -12
- data/lib/alexandria/book_providers/deastore.rb +27 -31
- data/lib/alexandria/book_providers/douban.rb +9 -13
- data/lib/alexandria/book_providers/ibs_it.rb +10 -10
- data/lib/alexandria/book_providers/mcu.rb +12 -18
- data/lib/alexandria/book_providers/proxis.rb +14 -22
- data/lib/alexandria/book_providers/pseudomarc.rb +8 -18
- data/lib/alexandria/book_providers/renaud.rb +16 -16
- data/lib/alexandria/book_providers/siciliano.rb +25 -38
- data/lib/alexandria/book_providers/thalia.rb +13 -16
- data/lib/alexandria/book_providers/webster_it.rb +14 -18
- data/lib/alexandria/book_providers/worldcat.rb +21 -25
- data/lib/alexandria/book_providers/z3950.rb +19 -23
- data/lib/alexandria/config.rb +2 -2
- data/lib/alexandria/execution_queue.rb +3 -1
- data/lib/alexandria/export_library.rb +19 -22
- data/lib/alexandria/import_library.rb +14 -18
- data/lib/alexandria/import_library_csv.rb +12 -30
- data/lib/alexandria/models/book.rb +7 -9
- data/lib/alexandria/models/library.rb +44 -44
- data/lib/alexandria/net.rb +1 -1
- data/lib/alexandria/preferences.rb +12 -57
- data/lib/alexandria/scanners.rb +10 -6
- data/lib/alexandria/scanners/cuecat.rb +2 -2
- data/lib/alexandria/smart_library.rb +12 -12
- data/lib/alexandria/ui.rb +5 -2
- data/lib/alexandria/ui/callbacks.rb +106 -65
- data/lib/alexandria/ui/completion_models.rb +55 -51
- data/lib/alexandria/ui/dialogs/about_dialog.rb +1 -1
- data/lib/alexandria/ui/dialogs/acquire_dialog.rb +25 -51
- data/lib/alexandria/ui/dialogs/alert_dialog.rb +13 -11
- data/lib/alexandria/ui/dialogs/bad_isbns_dialog.rb +2 -2
- data/lib/alexandria/ui/dialogs/barcode_animation.rb +39 -23
- data/lib/alexandria/ui/dialogs/book_properties_dialog.rb +16 -21
- data/lib/alexandria/ui/dialogs/book_properties_dialog_base.rb +23 -24
- data/lib/alexandria/ui/dialogs/export_dialog.rb +46 -45
- data/lib/alexandria/ui/dialogs/import_dialog.rb +26 -35
- data/lib/alexandria/ui/dialogs/misc_dialogs.rb +11 -11
- data/lib/alexandria/ui/dialogs/new_book_dialog.rb +47 -59
- data/lib/alexandria/ui/dialogs/new_book_dialog_manual.rb +14 -13
- data/lib/alexandria/ui/dialogs/new_smart_library_dialog.rb +12 -11
- data/lib/alexandria/ui/dialogs/preferences_dialog.rb +37 -43
- data/lib/alexandria/ui/dialogs/smart_library_properties_dialog.rb +9 -8
- data/lib/alexandria/ui/dialogs/smart_library_properties_dialog_base.rb +47 -53
- data/lib/alexandria/ui/dndable.rb +5 -4
- data/lib/alexandria/ui/icons.rb +19 -19
- data/lib/alexandria/ui/iconview.rb +7 -12
- data/lib/alexandria/ui/iconview_tooltips.rb +22 -109
- data/lib/alexandria/ui/init.rb +7 -15
- data/lib/alexandria/ui/libraries_combo.rb +54 -48
- data/lib/alexandria/ui/listview.rb +30 -85
- data/lib/alexandria/ui/multi_drag_treeview.rb +110 -107
- data/lib/alexandria/ui/sidepane.rb +23 -25
- data/lib/alexandria/ui/sound.rb +18 -27
- data/lib/alexandria/ui/ui_manager.rb +126 -204
- data/lib/alexandria/undo_manager.rb +2 -2
- data/lib/alexandria/version.rb +4 -4
- data/spec/alexandria/book_providers_spec.rb +7 -4
- data/spec/alexandria/library_spec.rb +13 -16
- data/spec/alexandria/scanners/cuecat_spec.rb +1 -2
- data/spec/alexandria/ui/dialogs_spec.rb +5 -1
- data/spec/alexandria/ui/main_app_spec.rb +3 -3
- data/{lib/alexandria/utils.rb → spec/alexandria/ui/sound_spec.rb} +6 -11
- data/spec/alexandria/ui/ui_utilities_spec.rb +3 -3
- data/spec/spec_helper.rb +2 -2
- data/util/rake/fileinstall.rb +17 -33
- data/util/rake/gettextgenerate.rb +2 -4
- data/util/rake/omfgenerate.rb +1 -3
- metadata +23 -11
- data/lib/alexandria/ui/gtk_thread_help.rb +0 -89
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (C) 2007 Marco Costantini
|
2
|
-
# Copyright (C) 2014 Matijs van Zuijlen
|
2
|
+
# Copyright (C) 2014, 2016 Matijs van Zuijlen
|
3
3
|
# based on ibs_it.rb by Claudio Belotti
|
4
4
|
#
|
5
5
|
# Alexandria is free software; you can redistribute it and/or
|
@@ -25,10 +25,10 @@ require 'open-uri'
|
|
25
25
|
module Alexandria
|
26
26
|
class BookProviders
|
27
27
|
class BOL_itProvider < GenericProvider
|
28
|
-
BASE_URI = 'http://www.bol.it'
|
28
|
+
BASE_URI = 'http://www.bol.it'.freeze
|
29
29
|
CACHE_DIR = File.join(Alexandria::Library::DIR, '.bol_it_cache')
|
30
30
|
REFERER = BASE_URI
|
31
|
-
LOCALE = 'libri' # possible locales are: "libri", "inglesi", "video", "musica", "choco"
|
31
|
+
LOCALE = 'libri'.freeze # possible locales are: "libri", "inglesi", "video", "musica", "choco"
|
32
32
|
def initialize
|
33
33
|
super('BOL_it', 'BOL (Italy)')
|
34
34
|
FileUtils.mkdir_p(CACHE_DIR) unless File.exist?(CACHE_DIR)
|
@@ -37,7 +37,7 @@ module Alexandria
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def search(criterion, type)
|
40
|
-
criterion = criterion.
|
40
|
+
criterion = criterion.encode('ISO-8859-1')
|
41
41
|
req = BASE_URI + '/' + LOCALE + '/'
|
42
42
|
req += case type
|
43
43
|
when SEARCH_BY_ISBN
|
@@ -84,8 +84,8 @@ module Alexandria
|
|
84
84
|
private
|
85
85
|
|
86
86
|
def to_book(data)
|
87
|
-
raise NoResultsError if /Scheda libro non completa \(TP null\)
|
88
|
-
data = data.
|
87
|
+
raise NoResultsError if data =~ /Scheda libro non completa \(TP null\)/
|
88
|
+
data = data.encode('UTF-8')
|
89
89
|
|
90
90
|
md = /<INPUT type =hidden name ="mailTitolo" value="([^"]+)/.match(data)
|
91
91
|
raise 'No title' unless md
|
@@ -103,25 +103,25 @@ module Alexandria
|
|
103
103
|
|
104
104
|
# raise unless
|
105
105
|
md = /<INPUT type =HIDDEN name ="mailEditore" value="([^"]+)/.match(data)
|
106
|
-
publisher = CGI.unescape(md[1].strip)
|
106
|
+
(publisher = CGI.unescape(md[1].strip)) || md
|
107
107
|
|
108
108
|
# raise unless
|
109
109
|
md = /<INPUT type =HIDDEN name ="mailFormato" value="([^"]+)/.match(data)
|
110
|
-
edition = CGI.unescape(md[1].strip)
|
110
|
+
(edition = CGI.unescape(md[1].strip)) || md
|
111
111
|
|
112
112
|
if (md = /#{edition}\ \;\|\ \;(\d+)\ \;\|\ \;/.match(data))
|
113
113
|
nr_pages = CGI.unescape(md[1].strip)
|
114
114
|
elsif (md = / (\d+) pagine \| /.match(data))
|
115
115
|
nr_pages = CGI.unescape(md[1].strip)
|
116
116
|
end
|
117
|
-
if nr_pages != '0'
|
117
|
+
if (nr_pages != '0') && !nr_pages.nil?
|
118
118
|
edition = nr_pages + ' p., ' + edition
|
119
119
|
end
|
120
120
|
|
121
121
|
publish_year = nil
|
122
122
|
if (md = /<INPUT type =HIDDEN name ="mailAnnoPubbl" value="([^"]+)/.match(data))
|
123
123
|
publish_year = CGI.unescape(md[1].strip).to_i
|
124
|
-
publish_year = nil if publish_year
|
124
|
+
publish_year = nil if publish_year.zero?
|
125
125
|
end
|
126
126
|
|
127
127
|
cover_url = BASE_URI + '/bol/includes/tornaImmagine.jsp?cdSoc=BL&ean=' + isbn[0..11] + '&tipoOggetto=PIB&cdSito=BL' # use "FRB" instead of "PIB" for smaller images
|
@@ -133,7 +133,7 @@ module Alexandria
|
|
133
133
|
end
|
134
134
|
|
135
135
|
medium_cover = CACHE_DIR + '/' + cover_filename
|
136
|
-
if File.size(medium_cover) > 43
|
136
|
+
if File.size(medium_cover) > 43 && (File.size(medium_cover) != 2382) # 2382 is the size of the fake image "copertina non disponibile"
|
137
137
|
puts medium_cover + ' has non-0 size' if $DEBUG
|
138
138
|
return [Book.new(title, authors, isbn, publisher, publish_year, edition), medium_cover]
|
139
139
|
end
|
@@ -147,7 +147,7 @@ module Alexandria
|
|
147
147
|
end
|
148
148
|
|
149
149
|
def clean_cache
|
150
|
-
# FIXME begin ... rescue ... end?
|
150
|
+
# FIXME: begin ... rescue ... end?
|
151
151
|
Dir.chdir(CACHE_DIR) do
|
152
152
|
Dir.glob('*.tmp') do |file|
|
153
153
|
puts 'removing ' + file if $DEBUG
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# -*- ruby -*-
|
2
2
|
#
|
3
3
|
# Copyright (C) 2009 Cathal Mc Ginley
|
4
|
-
# Copyright (C) 2011, 2014 Matijs van Zuijlen
|
4
|
+
# Copyright (C) 2011, 2014, 2016 Matijs van Zuijlen
|
5
5
|
#
|
6
6
|
# Alexandria is free software; you can redistribute it and/or
|
7
7
|
# modify it under the terms of the GNU General Public License as
|
@@ -31,8 +31,8 @@ module Alexandria
|
|
31
31
|
class DeaStoreProvider < WebsiteBasedProvider
|
32
32
|
include Alexandria::Logging
|
33
33
|
|
34
|
-
SITE = 'http://www.deastore.com'
|
35
|
-
BASE_SEARCH_URL = "#{SITE}/search/italian_books/0/%s/%s" # type/term
|
34
|
+
SITE = 'http://www.deastore.com'.freeze
|
35
|
+
BASE_SEARCH_URL = "#{SITE}/search/italian_books/0/%s/%s".freeze # type/term
|
36
36
|
|
37
37
|
def initialize
|
38
38
|
super('DeaStore', 'DeaStore (Italy)')
|
@@ -59,8 +59,8 @@ module Alexandria
|
|
59
59
|
|
60
60
|
def search(criterion, type)
|
61
61
|
begin
|
62
|
-
criterion = criterion.
|
63
|
-
rescue
|
62
|
+
criterion = criterion.encode('ISO-8859-1') # still needed??
|
63
|
+
rescue Encoding::UndefinedConversionError
|
64
64
|
log.info { "Cannot search for non-ISO-8859-1 terms at DeaStore : #{criterion}" }
|
65
65
|
raise NoResultsError
|
66
66
|
end
|
@@ -87,18 +87,16 @@ module Alexandria
|
|
87
87
|
|
88
88
|
def create_search_uri(search_type, search_term)
|
89
89
|
# bah! very, very similar to the siciliano code! refactor out this duplication
|
90
|
-
search_type_code = { SEARCH_BY_ISBN => 'isbn',
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
}[search_type] or 'keywords'
|
90
|
+
(search_type_code = { SEARCH_BY_ISBN => 'isbn',
|
91
|
+
SEARCH_BY_TITLE => 'title',
|
92
|
+
SEARCH_BY_AUTHORS => 'author',
|
93
|
+
SEARCH_BY_KEYWORD => 'keywords' }[search_type]) || 'keywords'
|
95
94
|
|
96
|
-
search_term_encoded =
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
end
|
95
|
+
search_term_encoded = if search_type == SEARCH_BY_ISBN
|
96
|
+
Library.canonicalise_isbn(search_term) # isbn-10
|
97
|
+
else
|
98
|
+
CGI.escape(search_term)
|
99
|
+
end
|
102
100
|
|
103
101
|
uri = BASE_SEARCH_URL % [search_type_code, search_term_encoded]
|
104
102
|
log.debug { uri }
|
@@ -142,7 +140,7 @@ module Alexandria
|
|
142
140
|
title_link = (content / :a).first
|
143
141
|
title = normalize(title_link.inner_text)
|
144
142
|
link_to_description = title_link['href']
|
145
|
-
lookup_url =
|
143
|
+
lookup_url = "#{SITE}#{link_to_description}"
|
146
144
|
|
147
145
|
authors = []
|
148
146
|
(content / 'a.info').each do |link|
|
@@ -245,17 +243,17 @@ module Alexandria
|
|
245
243
|
# cover
|
246
244
|
image_url = nil
|
247
245
|
if cover_link
|
248
|
-
if cover_link =~ /^http/
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
246
|
+
image_url = if cover_link =~ /^http/
|
247
|
+
# e.g. http://images.btol.com/ContentCafe/Jacket.aspx?\
|
248
|
+
# Return=1&Type=M&Value=9788873641803&password=\
|
249
|
+
# CC70580&userID=DEA40305
|
250
|
+
# seems not to work, or to be blank anyway, so set to nil
|
251
|
+
nil
|
252
|
+
elsif cover_link[0..0] != '/'
|
253
|
+
"#{SITE}/#{cover_link}"
|
254
|
+
else
|
255
|
+
"#{SITE}#{cover_link}"
|
256
|
+
end
|
259
257
|
log.debug { "Cover Image URL:: #{image_url}" }
|
260
258
|
end
|
261
259
|
book = Book.new(title, authors, isbn, publisher, publish_year, binding)
|
@@ -267,9 +265,7 @@ module Alexandria
|
|
267
265
|
end
|
268
266
|
|
269
267
|
def normalize(str)
|
270
|
-
unless str.nil?
|
271
|
-
str = str.squeeze(' ').strip
|
272
|
-
end
|
268
|
+
str = str.squeeze(' ').strip unless str.nil?
|
273
269
|
str
|
274
270
|
end
|
275
271
|
end
|
@@ -32,8 +32,8 @@ module Alexandria
|
|
32
32
|
class DoubanProvider < GenericProvider
|
33
33
|
include Alexandria::Logging
|
34
34
|
|
35
|
-
SITE = 'http://www.douban.com'
|
36
|
-
BASE_URL = 'http://api.douban.com/book/subjects?q=%s&max-results=5&alt=json'
|
35
|
+
SITE = 'http://www.douban.com'.freeze
|
36
|
+
BASE_URL = 'http://api.douban.com/book/subjects?q=%s&max-results=5&alt=json'.freeze
|
37
37
|
|
38
38
|
def initialize
|
39
39
|
super('Douban', 'Douban (China)')
|
@@ -51,9 +51,7 @@ module Alexandria
|
|
51
51
|
search_response = transport.get_response(URI.parse(request_url))
|
52
52
|
|
53
53
|
results = parse_search_result(search_response.body)
|
54
|
-
if results.
|
55
|
-
raise NoResultsError
|
56
|
-
end
|
54
|
+
raise NoResultsError if results.empty?
|
57
55
|
|
58
56
|
if type == SEARCH_BY_ISBN
|
59
57
|
return results.first
|
@@ -97,9 +95,7 @@ module Alexandria
|
|
97
95
|
pubdate = nil
|
98
96
|
binding = nil
|
99
97
|
for av in item['db:attribute']
|
100
|
-
if av['@name'] == 'isbn13'
|
101
|
-
isbn = av['$t']
|
102
|
-
end
|
98
|
+
isbn = av['$t'] if av['@name'] == 'isbn13'
|
103
99
|
if av['@name'] == 'publisher'
|
104
100
|
publisher = av['$t']
|
105
101
|
end
|
@@ -110,11 +106,11 @@ module Alexandria
|
|
110
106
|
binding = av['$t']
|
111
107
|
end
|
112
108
|
end
|
113
|
-
if item['author']
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
109
|
+
authors = if item['author']
|
110
|
+
item['author'].map { |a| a['name']['$t'] }
|
111
|
+
else
|
112
|
+
[]
|
113
|
+
end
|
118
114
|
image_url = nil
|
119
115
|
for av in item['link']
|
120
116
|
if av['@rel'] == 'image'
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (C) 2005-2006 Claudio Belotti
|
2
|
-
# Copyright (C) 2014 Matijs van Zuijlen
|
2
|
+
# Copyright (C) 2014, 2016 Matijs van Zuijlen
|
3
3
|
#
|
4
4
|
# Alexandria is free software; you can redistribute it and/or
|
5
5
|
# modify it under the terms of the GNU General Public License as
|
@@ -24,7 +24,7 @@ require 'open-uri'
|
|
24
24
|
module Alexandria
|
25
25
|
class BookProviders
|
26
26
|
class IBS_itProvider < GenericProvider
|
27
|
-
BASE_URI = 'http://www.internetbookshop.it'
|
27
|
+
BASE_URI = 'http://www.internetbookshop.it'.freeze
|
28
28
|
CACHE_DIR = File.join(Alexandria::Library::DIR, '.ibs_it_cache')
|
29
29
|
REFERER = BASE_URI
|
30
30
|
def initialize
|
@@ -35,7 +35,7 @@ module Alexandria
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def search(criterion, type)
|
38
|
-
criterion = criterion.
|
38
|
+
criterion = criterion.encode('ISO-8859-1')
|
39
39
|
req = BASE_URI + '/ser/'
|
40
40
|
req += case type
|
41
41
|
when SEARCH_BY_ISBN
|
@@ -80,8 +80,8 @@ module Alexandria
|
|
80
80
|
private
|
81
81
|
|
82
82
|
def to_book(data)
|
83
|
-
raise NoResultsError if /<b>Il libro che hai cercato non è presente nel nostro catalogo<\/b><br
|
84
|
-
data = data.
|
83
|
+
raise NoResultsError if data =~ /<b>Il libro che hai cercato non è presente nel nostro catalogo<\/b><br>/
|
84
|
+
data = data.encode('UTF-8')
|
85
85
|
|
86
86
|
md = />Titolo<\/td><td valign="top" class="lbarrasup">([^<]+)/.match(data)
|
87
87
|
raise 'No title' unless md
|
@@ -98,16 +98,16 @@ module Alexandria
|
|
98
98
|
|
99
99
|
# raise "No publisher" unless
|
100
100
|
md = /<b>Editore<\/b><\/td>.+<b>([^<]+)/.match(data)
|
101
|
-
publisher = CGI.unescape(md[1].strip)
|
101
|
+
(publisher = CGI.unescape(md[1].strip)) || md
|
102
102
|
|
103
103
|
# raise "No edition" unless
|
104
104
|
md = /Dati<\/b><\/td><td valign="top">([^<]+)/.match(data)
|
105
|
-
edition = CGI.unescape(md[1].strip)
|
105
|
+
(edition = CGI.unescape(md[1].strip)) || md
|
106
106
|
|
107
107
|
publish_year = nil
|
108
108
|
if (md = /Anno<\/b><\/td><td valign="top">([^<]+)/.match(data))
|
109
109
|
publish_year = CGI.unescape(md[1].strip).to_i
|
110
|
-
publish_year = nil if publish_year
|
110
|
+
publish_year = nil if publish_year.zero?
|
111
111
|
end
|
112
112
|
|
113
113
|
md = /src="http:\/\/giotto.ibs.it\/cop\/copt13.asp\?f=(\d+)">/.match(data)
|
@@ -120,7 +120,7 @@ module Alexandria
|
|
120
120
|
end
|
121
121
|
|
122
122
|
medium_cover = CACHE_DIR + '/' + cover_filename
|
123
|
-
if File.size(medium_cover) > 0
|
123
|
+
if File.size(medium_cover) > 0 && (File.size(medium_cover) != 1822) # 1822 is the size of the fake image "copertina non disponibile"
|
124
124
|
puts medium_cover + ' has non-0 size' if $DEBUG
|
125
125
|
return [Book.new(title, authors, isbn, publisher, publish_year, edition), medium_cover]
|
126
126
|
end
|
@@ -134,7 +134,7 @@ module Alexandria
|
|
134
134
|
end
|
135
135
|
|
136
136
|
def clean_cache
|
137
|
-
# FIXME begin ... rescue ... end?
|
137
|
+
# FIXME: begin ... rescue ... end?
|
138
138
|
Dir.chdir(CACHE_DIR) do
|
139
139
|
Dir.glob('*.tmp') do |file|
|
140
140
|
puts 'removing ' + file if $DEBUG
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# Copyright (C) 2004 Javier Fernandez-Sanguino
|
2
2
|
# Copyright (C) 2007 Javier Fernandez-Sanguino and Marco Costantini
|
3
|
-
# Copyright (C) 2011 Matijs van Zuijlen
|
3
|
+
# Copyright (C) 2011, 2016 Matijs van Zuijlen
|
4
4
|
#
|
5
5
|
# Alexandria is free software; you can redistribute it and/or
|
6
6
|
# modify it under the terms of the GNU General Public License as
|
@@ -32,10 +32,10 @@ module Alexandria
|
|
32
32
|
|
33
33
|
LANGUAGES = {
|
34
34
|
'es' => '1'
|
35
|
-
}
|
35
|
+
}.freeze
|
36
36
|
|
37
37
|
# BASE_URI = "http://www.mcu.es/cgi-bin/BRSCGI3701?"
|
38
|
-
BASE_URI = 'http://www.mcu.es/cgi-brs/BasesHTML/isbn/BRSCGI?'
|
38
|
+
BASE_URI = 'http://www.mcu.es/cgi-brs/BasesHTML/isbn/BRSCGI?'.freeze
|
39
39
|
def initialize
|
40
40
|
super('MCU', _('Spanish Culture Ministry'))
|
41
41
|
# No preferences
|
@@ -44,12 +44,7 @@ module Alexandria
|
|
44
44
|
|
45
45
|
def search(criterion, type)
|
46
46
|
prefs.read
|
47
|
-
|
48
|
-
criterion = criterion.convert('ISO-8859-1', 'UTF-8') # still needed??
|
49
|
-
rescue GLib::ConvertError
|
50
|
-
log.info { "Cannot search for non-ISO-8859-1 terms at MCU : #{criterion}" }
|
51
|
-
raise NoResultsError
|
52
|
-
end
|
47
|
+
criterion = criterion.encode('ISO-8859-1') # still needed??
|
53
48
|
print "Doing search with MCU #{criterion}, type: #{type}\n" if $DEBUG # for DEBUGing
|
54
49
|
req = BASE_URI + 'CMD=VERLST&BASE=ISBN&DOCS=1-15&CONF=AEISPA.cnf&OPDEF=AND&DOCS=1-1000&SEPARADOR=&'
|
55
50
|
req += case type
|
@@ -71,9 +66,8 @@ module Alexandria
|
|
71
66
|
products = {}
|
72
67
|
print "Request page is #{req}\n" if $DEBUG # for DEBUGing
|
73
68
|
transport.get(URI.parse(req)).each do |line|
|
74
|
-
# line = line.convert("ISO-8859-1", "UTF-8")
|
75
69
|
print "Reading line: #{line}" if $DEBUG # for DEBUGing
|
76
|
-
if (line =~ /CMD=VERDOC.*&DOCN=([^&]*)&NDOC=([^&]*)/)
|
70
|
+
if (line =~ /CMD=VERDOC.*&DOCN=([^&]*)&NDOC=([^&]*)/) && (!products[Regexp.last_match[1]]) && (book = parseBook(Regexp.last_match[1], Regexp.last_match[2]))
|
77
71
|
products[Regexp.last_match[1]] = book
|
78
72
|
puts Regexp.last_match[1] if $DEBUG # for DEBUGing
|
79
73
|
end
|
@@ -109,11 +103,11 @@ module Alexandria
|
|
109
103
|
# - CDU - Last update
|
110
104
|
|
111
105
|
# There seems to be an issue with accented chars..
|
112
|
-
line = line.
|
106
|
+
line = line.encode('UTF-8')
|
113
107
|
print "Reading line (robotstate #{robotstate}): #{line}" if $DEBUG # for DEBUGing
|
114
|
-
if line =~ /^<\/td>$/
|
108
|
+
if line =~ /^<\/td>$/ || line =~ /^<\/tr>$/
|
115
109
|
robotstate = 0
|
116
|
-
elsif robotstate == 1
|
110
|
+
elsif (robotstate == 1) && line =~ /^([^<]+)</
|
117
111
|
author = Regexp.last_match[1].gsub(' ', ' ').sub(/ +$/, '')
|
118
112
|
if author.length > 3
|
119
113
|
# Only add authors of appropiate length
|
@@ -121,20 +115,20 @@ module Alexandria
|
|
121
115
|
print "Authors are #{product['authors']}\n" if $DEBUG # for DEBUGing
|
122
116
|
robotstate = 0
|
123
117
|
end
|
124
|
-
elsif robotstate == 2
|
118
|
+
elsif (robotstate == 2) && line =~ /^(.*)$/ # The title es the next line to title declaration and has not tags on web src code
|
125
119
|
product['name'] = Regexp.last_match[1].strip
|
126
120
|
print "Name is #{product['name']}\n" if $DEBUG # for DEBUGing
|
127
121
|
robotstate = 0
|
128
|
-
elsif robotstate == 3
|
122
|
+
elsif (robotstate == 3) && line =~ /^([0-9]+-[0-9]+-[0-9]+-[0-9]+-[0-9]).*/
|
129
123
|
product['isbn'] = Regexp.last_match[1]
|
130
124
|
print "ISBN is #{product['isbn']}\n" if $DEBUG # for DEBUGing
|
131
125
|
robotstate = 0
|
132
|
-
elsif robotstate == 4
|
126
|
+
elsif (robotstate == 4) && line =~ /^([^<]+)</
|
133
127
|
product['manufacturer'] = Regexp.last_match[1].strip
|
134
128
|
print "Manufacturer is #{product['manufacturer']}\n" if $DEBUG # for DEBUGing
|
135
129
|
robotstate = 0
|
136
130
|
# elsif robotstate == 5 and line =~ /^([^<]+)</
|
137
|
-
elsif robotstate == 5
|
131
|
+
elsif (robotstate == 5) && line =~ /<span>([^<]+)</
|
138
132
|
product['media'] = Regexp.last_match[1].strip
|
139
133
|
print "Media is #{product['media']}\n" if $DEBUG # for DEBUGing
|
140
134
|
robotstate = 0
|
@@ -1,5 +1,5 @@
|
|
1
1
|
# Copyright (C) 2009 Cathal Mc Ginley
|
2
|
-
# Copyright (C) 2014
|
2
|
+
# Copyright (C) 2014-2016 Matijs van Zuijlen
|
3
3
|
#
|
4
4
|
# Alexandria is free software; you can redistribute it and/or
|
5
5
|
# modify it under the terms of the GNU General Public License as
|
@@ -34,11 +34,11 @@ module Alexandria
|
|
34
34
|
# it adds most to Alexandria (Amazon already has French and
|
35
35
|
# English titles).
|
36
36
|
|
37
|
-
SITE = 'http://www.proxis.nl'
|
37
|
+
SITE = 'http://www.proxis.nl'.freeze
|
38
38
|
BASE_SEARCH_URL = "#{SITE}/NLNL/Search/IndexGSA.aspx?search=%s" \
|
39
|
-
'&shop=100001NL&SelRubricLevel1Id=100001NL'
|
39
|
+
'&shop=100001NL&SelRubricLevel1Id=100001NL'.freeze
|
40
40
|
ISBN_REDIRECT_BASE_URL = "#{SITE}/NLNL/Search/Index.aspx?search=%s" \
|
41
|
-
'&shop=100001NL&SelRubricLevel1Id=100001NL'
|
41
|
+
'&shop=100001NL&SelRubricLevel1Id=100001NL'.freeze
|
42
42
|
|
43
43
|
def initialize
|
44
44
|
super('Proxis', 'Proxis (Belgium)')
|
@@ -47,10 +47,6 @@ module Alexandria
|
|
47
47
|
prefs.read
|
48
48
|
end
|
49
49
|
|
50
|
-
## criterion = criterion.convert("windows-1252", "UTF-8")
|
51
|
-
## is the above still needed??
|
52
|
-
## current pages are returned in UTF-8, so I think probably not!
|
53
|
-
|
54
50
|
def search(criterion, type)
|
55
51
|
req = create_search_uri(type, criterion)
|
56
52
|
puts req if $DEBUG
|
@@ -75,12 +71,12 @@ module Alexandria
|
|
75
71
|
|
76
72
|
def get_book_from_search_result(result)
|
77
73
|
log.debug { "Fetching book from #{result[:lookup_url]}" }
|
78
|
-
html_data =
|
74
|
+
html_data = transport.get_response(URI.parse(result[:lookup_url]))
|
79
75
|
parse_result_data(html_data.body)
|
80
76
|
end
|
81
77
|
|
82
78
|
def url(book)
|
83
|
-
if book.isbn.nil?
|
79
|
+
if book.isbn.nil? || book.isbn.empty?
|
84
80
|
ISBN_REDIRECT_BASE_URL % Library.canonicalise_ean(book.isbn)
|
85
81
|
end
|
86
82
|
end
|
@@ -107,7 +103,7 @@ module Alexandria
|
|
107
103
|
def parse_search_result_data(html)
|
108
104
|
doc = html_to_doc(html)
|
109
105
|
book_search_results = []
|
110
|
-
items =
|
106
|
+
items = doc.search('table.searchResult tr')
|
111
107
|
items.each do |item|
|
112
108
|
result = {}
|
113
109
|
title_link = item % 'h5 a'
|
@@ -129,9 +125,7 @@ module Alexandria
|
|
129
125
|
def data_for_header(th)
|
130
126
|
tr = th.parent
|
131
127
|
td = tr.at('td')
|
132
|
-
if td
|
133
|
-
text_of(td)
|
134
|
-
end
|
128
|
+
text_of(td) if td
|
135
129
|
end
|
136
130
|
|
137
131
|
def parse_result_data(html)
|
@@ -181,14 +175,12 @@ module Alexandria
|
|
181
175
|
|
182
176
|
image_url = nil
|
183
177
|
if (cover_img = doc.at("img[@id$='imgProduct']"))
|
184
|
-
if cover_img['src'] =~ /^http/
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
if image_url =~ /ProductNoCover/
|
190
|
-
image_url = nil
|
191
|
-
end
|
178
|
+
image_url = if cover_img['src'] =~ /^http/
|
179
|
+
cover_img['src']
|
180
|
+
else
|
181
|
+
"#{SITE}/#{cover_img['src']}" # TODO: use html <base>
|
182
|
+
end
|
183
|
+
image_url = nil if image_url =~ /ProductNoCover/
|
192
184
|
end
|
193
185
|
|
194
186
|
book = Book.new(book_data[:title], book_data[:authors],
|